/** Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com> */ public class PatternsTest { @ClassRule public static AkkaJUnitActorSystemResource actorSystemResource = new AkkaJUnitActorSystemResource("JavaAPI", AkkaSpec.testConf()); private final ActorSystem system = actorSystemResource.getSystem(); @Test public void useAsk() throws Exception { ActorRef testActor = system.actorOf(Props.create(JavaAPITestActor.class), "test"); assertEquals( "Ask should return expected answer", JavaAPITestActor.ANSWER, Await.result(ask(testActor, "hey!", 3000), Duration.create(3, "seconds"))); } @Test public void useAskWithActorSelection() throws Exception { ActorRef testActor = system.actorOf(Props.create(JavaAPITestActor.class), "test2"); ActorSelection selection = system.actorSelection("/user/test2"); ActorIdentity id = (ActorIdentity) Await.result(ask(selection, new Identify("yo!"), 3000), Duration.create(3, "seconds")); assertEquals("Ask (Identify) should return the proper ActorIdentity", testActor, id.getRef()); } @Test public void usePipe() throws Exception { TestProbe probe = new TestProbe(system); pipe(Futures.successful("ho!"), system.dispatcher()).to(probe.ref()); probe.expectMsg("ho!"); } @Test public void usePipeWithActorSelection() throws Exception { TestProbe probe = new TestProbe(system); ActorSelection selection = system.actorSelection(probe.ref().path()); pipe(Futures.successful("hi!"), system.dispatcher()).to(selection); probe.expectMsg("hi!"); } }
public class RouterViaProgramDocTest { @ClassRule public static AkkaJUnitActorSystemResource actorSystemResource = new AkkaJUnitActorSystemResource("RouterViaProgramDocTest"); private final ActorSystem system = actorSystemResource.getSystem(); private static class JavaTestKitWithSelf extends JavaTestKit { public JavaTestKitWithSelf(ActorSystem system) { super(system); } /** Wrap `getRef()` so our examples look like they're within a normal actor. */ public ActorRef getSelf() { return getRef(); } } @SuppressWarnings("unused") @Test public void demonstrateRouteesFromPaths() { new JavaTestKit(system) { { // #programmaticRoutingRouteePaths ActorRef actor1 = system.actorOf(Props.create(ExampleActor.class), "actor1"); ActorRef actor2 = system.actorOf(Props.create(ExampleActor.class), "actor2"); ActorRef actor3 = system.actorOf(Props.create(ExampleActor.class), "actor3"); Iterable<String> routees = Arrays.asList(new String[] {"/user/actor1", "/user/actor2", "/user/actor3"}); ActorRef router = system.actorOf(Props.empty().withRouter(new RoundRobinRouter(routees))); // #programmaticRoutingRouteePaths for (int i = 1; i <= 6; i++) { router.tell(new ExampleActor.Message(i), ActorRef.noSender()); } } }; } @Test public void demonstrateBroadcast() { new JavaTestKitWithSelf(system) { { ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5))); // #broadcastDavyJonesWarning router.tell(new Broadcast("Watch out for Davy Jones' locker"), getSelf()); // #broadcastDavyJonesWarning receiveN(5, duration("5 seconds")); } }; } @Test public void demonstratePoisonPill() { new JavaTestKitWithSelf(system) { { ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5))); watch(router); // #poisonPill router.tell(PoisonPill.getInstance(), getSelf()); // #poisonPill expectMsgClass(Terminated.class); } }; } @Test public void demonstrateBroadcastOfPoisonPill() { new JavaTestKitWithSelf(system) { { ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5))); watch(router); // #broadcastPoisonPill router.tell(new Broadcast(PoisonPill.getInstance()), getSelf()); // #broadcastPoisonPill expectMsgClass(Terminated.class); } }; } @Test public void demonstrateKill() { new JavaTestKitWithSelf(system) { { ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5))); watch(router); // #kill router.tell(Kill.getInstance(), getSelf()); // #kill expectMsgClass(Terminated.class); } }; } @Test public void demonstrateBroadcastOfKill() { new JavaTestKitWithSelf(system) { { ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5))); watch(router); // #broadcastKill router.tell(new Broadcast(Kill.getInstance()), getSelf()); // #broadcastKill expectMsgClass(Terminated.class); } }; } }
public class TestKitDocTest { @ClassRule public static AkkaJUnitActorSystemResource actorSystemResource = new AkkaJUnitActorSystemResource( "TestKitDocTest", ConfigFactory.parseString("akka.loggers = [akka.testkit.TestEventListener]")); private final ActorSystem system = actorSystemResource.getSystem(); // #test-actor-ref static class MyActor extends UntypedActor { public void onReceive(Object o) throws Exception { if (o.equals("say42")) { getSender().tell(42, getSelf()); } else if (o instanceof Exception) { throw (Exception) o; } } public boolean testMe() { return true; } } @Test public void demonstrateTestActorRef() { final Props props = Props.create(MyActor.class); final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testA"); final MyActor actor = ref.underlyingActor(); assertTrue(actor.testMe()); } // #test-actor-ref @Test public void demonstrateAsk() throws Exception { // #test-behavior final Props props = Props.create(MyActor.class); final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testB"); final Future<Object> future = akka.pattern.Patterns.ask(ref, "say42", 3000); assertTrue(future.isCompleted()); assertEquals(42, Await.result(future, Duration.Zero())); // #test-behavior } @Test public void demonstrateExceptions() { // #test-expecting-exceptions final Props props = Props.create(MyActor.class); final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "myActor"); try { ref.receive(new Exception("expected")); fail("expected an exception to be thrown"); } catch (Exception e) { assertEquals("expected", e.getMessage()); } // #test-expecting-exceptions } @Test public void demonstrateWithin() { // #test-within new JavaTestKit(system) { { getRef().tell(42, ActorRef.noSender()); new Within(Duration.Zero(), Duration.create(1, "second")) { // do not put code outside this method, will run afterwards public void run() { assertEquals((Integer) 42, expectMsgClass(Integer.class)); } }; } }; // #test-within } @Test public void demonstrateExpectMsg() { // #test-expectmsg new JavaTestKit(system) { { getRef().tell(42, ActorRef.noSender()); final String out = new ExpectMsg<String>("match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in instanceof Integer) { return "match"; } else { throw noMatch(); } } }.get(); // this extracts the received message assertEquals("match", out); } }; // #test-expectmsg } @Test public void demonstrateReceiveWhile() { // #test-receivewhile new JavaTestKit(system) { { getRef().tell(42, ActorRef.noSender()); getRef().tell(43, ActorRef.noSender()); getRef().tell("hello", ActorRef.noSender()); final String[] out = new ReceiveWhile<String>(String.class, duration("1 second")) { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in instanceof Integer) { return in.toString(); } else { throw noMatch(); } } }.get(); // this extracts the received messages assertArrayEquals(new String[] {"42", "43"}, out); expectMsgEquals("hello"); } }; // #test-receivewhile new JavaTestKit(system) { { // #test-receivewhile-full new ReceiveWhile<String>( // type of array to be created must match ... String.class, // ... this class which is needed to that end duration("100 millis"), // maximum collect time duration("50 millis"), // maximum time between messages 12 // maximum number of messages to collect ) { // #match-elided protected String match(Object in) { throw noMatch(); } // #match-elided }; // #test-receivewhile-full } }; } @Test public void demonstrateAwaitCond() { // #test-awaitCond new JavaTestKit(system) { { getRef().tell(42, ActorRef.noSender()); new AwaitCond( duration("1 second"), // maximum wait time duration("100 millis") // interval at which to check the condition ) { // do not put code outside this method, will run afterwards protected boolean cond() { // typically used to wait for something to start up return msgAvailable(); } }; } }; // #test-awaitCond } @Test public void demonstrateAwaitAssert() { // #test-awaitAssert new JavaTestKit(system) { { getRef().tell(42, ActorRef.noSender()); new AwaitAssert( duration("1 second"), // maximum wait time duration("100 millis") // interval at which to check the condition ) { // do not put code outside this method, will run afterwards protected void check() { assertEquals(msgAvailable(), true); } }; } }; // #test-awaitAssert } @Test @SuppressWarnings({"unchecked", "unused"}) // due to generic varargs public void demonstrateExpect() { new JavaTestKit(system) { { getRef().tell("hello", ActorRef.noSender()); getRef().tell("hello", ActorRef.noSender()); getRef().tell("hello", ActorRef.noSender()); getRef().tell("world", ActorRef.noSender()); getRef().tell(42, ActorRef.noSender()); getRef().tell(42, ActorRef.noSender()); // #test-expect final String hello = expectMsgEquals("hello"); final Object any = expectMsgAnyOf("hello", "world"); final Object[] all = expectMsgAllOf("hello", "world"); final int i = expectMsgClass(Integer.class); final Number j = expectMsgAnyClassOf(Integer.class, Long.class); expectNoMsg(); // #test-expect getRef().tell("receveN-1", ActorRef.noSender()); getRef().tell("receveN-2", ActorRef.noSender()); // #test-expect final Object[] two = receiveN(2); // #test-expect assertEquals("hello", hello); assertEquals("hello", any); assertEquals(42, i); assertEquals(42, j); assertArrayEquals(new String[] {"hello", "world"}, all); } }; } @Test public void demonstrateIgnoreMsg() { // #test-ignoreMsg new JavaTestKit(system) { { // ignore all Strings new IgnoreMsg() { protected boolean ignore(Object msg) { return msg instanceof String; } }; getRef().tell("hello", ActorRef.noSender()); getRef().tell(42, ActorRef.noSender()); expectMsgEquals(42); // remove message filter ignoreNoMsg(); getRef().tell("hello", ActorRef.noSender()); expectMsgEquals("hello"); } }; // #test-ignoreMsg } @Test public void demonstrateDilated() { // #duration-dilation new JavaTestKit(system) { { final Duration original = duration("1 second"); final Duration stretched = dilated(original); assertTrue("dilated", stretched.gteq(original)); } }; // #duration-dilation } @Test public void demonstrateProbe() { // #test-probe new JavaTestKit(system) { { // simple actor which just forwards messages class Forwarder extends UntypedActor { final ActorRef target; @SuppressWarnings("unused") public Forwarder(ActorRef target) { this.target = target; } public void onReceive(Object msg) { target.forward(msg, getContext()); } } // create a test probe final JavaTestKit probe = new JavaTestKit(system); // create a forwarder, injecting the probe’s testActor final Props props = Props.create(Forwarder.class, this, probe.getRef()); final ActorRef forwarder = system.actorOf(props, "forwarder"); // verify correct forwarding forwarder.tell(42, getRef()); probe.expectMsgEquals(42); assertEquals(getRef(), probe.getLastSender()); } }; // #test-probe } @Test public void demonstrateSpecialProbe() { // #test-special-probe new JavaTestKit(system) { { class MyProbe extends JavaTestKit { public MyProbe() { super(system); } public void assertHello() { expectMsgEquals("hello"); } } final MyProbe probe = new MyProbe(); probe.getRef().tell("hello", ActorRef.noSender()); probe.assertHello(); } }; // #test-special-probe } @Test public void demonstrateWatch() { final ActorRef target = system.actorOf(Props.create(MyActor.class)); // #test-probe-watch new JavaTestKit(system) { { final JavaTestKit probe = new JavaTestKit(system); probe.watch(target); target.tell(PoisonPill.getInstance(), ActorRef.noSender()); final Terminated msg = probe.expectMsgClass(Terminated.class); assertEquals(msg.getActor(), target); } }; // #test-probe-watch } @Test public void demonstrateReply() { // #test-probe-reply new JavaTestKit(system) { { final JavaTestKit probe = new JavaTestKit(system); probe.getRef().tell("hello", getRef()); probe.expectMsgEquals("hello"); probe.reply("world"); expectMsgEquals("world"); assertEquals(probe.getRef(), getLastSender()); } }; // #test-probe-reply } @Test public void demonstrateForward() { // #test-probe-forward new JavaTestKit(system) { { final JavaTestKit probe = new JavaTestKit(system); probe.getRef().tell("hello", getRef()); probe.expectMsgEquals("hello"); probe.forward(getRef()); expectMsgEquals("hello"); assertEquals(getRef(), getLastSender()); } }; // #test-probe-forward } @Test public void demonstrateWithinProbe() { try { // #test-within-probe new JavaTestKit(system) { { final JavaTestKit probe = new JavaTestKit(system); new Within(duration("1 second")) { public void run() { probe.expectMsgEquals("hello"); } }; } }; // #test-within-probe } catch (AssertionError e) { // expected to fail } } @Test public void demonstrateAutoPilot() { // #test-auto-pilot new JavaTestKit(system) { { final JavaTestKit probe = new JavaTestKit(system); // install auto-pilot probe.setAutoPilot( new TestActor.AutoPilot() { public AutoPilot run(ActorRef sender, Object msg) { sender.tell(msg, ActorRef.noSender()); return noAutoPilot(); } }); // first one is replied to directly ... probe.getRef().tell("hello", getRef()); expectMsgEquals("hello"); // ... but then the auto-pilot switched itself off probe.getRef().tell("world", getRef()); expectNoMsg(); } }; // #test-auto-pilot } // only compilation public void demonstrateCTD() { // #calling-thread-dispatcher system.actorOf(Props.create(MyActor.class).withDispatcher(CallingThreadDispatcher.Id())); // #calling-thread-dispatcher } @Test public void demonstrateEventFilter() { // #test-event-filter new JavaTestKit(system) { { assertEquals("TestKitDocTest", system.name()); final ActorRef victim = system.actorOf(Props.empty(), "victim"); final int result = new EventFilter<Integer>(ActorKilledException.class) { protected Integer run() { victim.tell(Kill.getInstance(), ActorRef.noSender()); return 42; } }.from("akka://TestKitDocTest/user/victim").occurrences(1).exec(); assertEquals(42, result); } }; // #test-event-filter } }
public class ParentChildTest { @ClassRule public static AkkaJUnitActorSystemResource actorSystemResource = new AkkaJUnitActorSystemResource( "TestKitDocTest", ConfigFactory.parseString("akka.loggers = [akka.testkit.TestEventListener]")); private final ActorSystem system = actorSystemResource.getSystem(); // #test-example static class Parent extends UntypedActor { final ActorRef child = context().actorOf(Props.create(Child.class), "child"); boolean ponged = false; @Override public void onReceive(Object message) throws Exception { if ("pingit".equals(message)) { child.tell("ping", self()); } else if ("pong".equals(message)) { ponged = true; } else { unhandled(message); } } } static class Child extends UntypedActor { @Override public void onReceive(Object message) throws Exception { if ("ping".equals(message)) { context().parent().tell("pong", self()); } else { unhandled(message); } } } // #test-example static // #test-dependentchild class DependentChild extends UntypedActor { private final ActorRef parent; public DependentChild(ActorRef parent) { this.parent = parent; } @Override public void onReceive(Object message) throws Exception { if ("ping".equals(message)) { parent.tell("pong", self()); } else { unhandled(message); } } } // #test-dependentchild static // #test-dependentparent class DependentParent extends UntypedActor { final ActorRef child; boolean ponged = false; public DependentParent(Props childProps) { child = context().actorOf(childProps, "child"); } @Override public void onReceive(Object message) throws Exception { if ("pingit".equals(message)) { child.tell("ping", self()); } else if ("pong".equals(message)) { ponged = true; } else { unhandled(message); } } } // #test-dependentparent static // #test-dependentparent-generic class GenericDependentParent extends UntypedActor { final ActorRef child; boolean ponged = false; public GenericDependentParent(Function<ActorRefFactory, ActorRef> childMaker) throws Exception { child = childMaker.apply(context()); } @Override public void onReceive(Object message) throws Exception { if ("pingit".equals(message)) { child.tell("ping", self()); } else if ("pong".equals(message)) { ponged = true; } else { unhandled(message); } } } // #test-dependentparent-generic @Test public void testingWithoutParent() { TestProbe probe = new TestProbe(system); ActorRef child = system.actorOf(Props.create(DependentChild.class, probe.ref())); probe.send(child, "ping"); probe.expectMsg("pong"); } @Test public void testingWithCustomProps() { TestProbe probe = new TestProbe(system); Props childProps = Props.create(MockedChild.class); TestActorRef<DependentParent> parent = TestActorRef.create(system, Props.create(DependentParent.class, childProps)); probe.send(parent, "pingit"); // test some parent state change assertTrue(parent.underlyingActor().ponged == true || parent.underlyingActor().ponged == false); } @Test public void testingWithChildProbe() throws Exception { final TestProbe probe = new TestProbe(system); // #child-maker-test Function<ActorRefFactory, ActorRef> maker = new Function<ActorRefFactory, ActorRef>() { @Override public ActorRef apply(ActorRefFactory param) throws Exception { return probe.ref(); } }; ActorRef parent = system.actorOf(Props.create(GenericDependentParent.class, maker)); // #child-maker-test probe.send(parent, "pingit"); probe.expectMsg("ping"); } public void exampleProdActorFactoryFunction() throws Exception { // #child-maker-prod Function<ActorRefFactory, ActorRef> maker = new Function<ActorRefFactory, ActorRef>() { @Override public ActorRef apply(ActorRefFactory f) throws Exception { return f.actorOf(Props.create(Child.class)); } }; ActorRef parent = system.actorOf(Props.create(GenericDependentParent.class, maker)); // #child-maker-prod } static // #test-fabricated-parent-creator class FabricatedParentCreator implements Creator<Actor> { private final TestProbe proxy; public FabricatedParentCreator(TestProbe proxy) { this.proxy = proxy; } @Override public Actor create() throws Exception { return new UntypedActor() { final ActorRef child = context().actorOf(Props.create(Child.class), "child"); @Override public void onReceive(Object x) throws Exception { if (sender().equals(child)) { proxy.ref().forward(x, context()); } else { child.forward(x, context()); } } }; } } // #test-fabricated-parent-creator @Test public void testProbeParentTest() throws Exception { // #test-TestProbe-parent JavaTestKit parent = new JavaTestKit(system); ActorRef child = parent.childActorOf(Props.create(Child.class)); parent.send(child, "ping"); parent.expectMsgEquals("pong"); // #test-TestProbe-parent } @Test public void fabricatedParentTestsItsChildResponses() throws Exception { // didn't put final on these in order to make the parent fit in one line in the html docs // #test-fabricated-parent TestProbe proxy = new TestProbe(system); ActorRef parent = system.actorOf(Props.create(new FabricatedParentCreator(proxy))); proxy.send(parent, "ping"); proxy.expectMsg("pong"); // #test-fabricated-parent } }
public class UntypedActorDocTest { @ClassRule public static AkkaJUnitActorSystemResource actorSystemResource = new AkkaJUnitActorSystemResource("UntypedActorDocTest", AkkaSpec.testConf()); private final ActorSystem system = actorSystemResource.getSystem(); // #creating-props-config static class MyActorC implements Creator<MyActor> { @Override public MyActor create() { return new MyActor("..."); } } // #creating-props-config @SuppressWarnings("unused") @Test public void createProps() { // #creating-props-config Props props1 = Props.create(MyUntypedActor.class); Props props2 = Props.create(MyActor.class, "..."); Props props3 = Props.create(new MyActorC()); // #creating-props-config } // #parametric-creator static class ParametricCreator<T extends MyActor> implements Creator<T> { @Override public T create() { // ... fabricate actor here // #parametric-creator return null; // #parametric-creator } } // #parametric-creator @Test public void systemActorOf() { // #system-actorOf // ActorSystem is a heavy object: create only one per application final ActorSystem system = ActorSystem.create("MySystem"); final ActorRef myActor = system.actorOf(Props.create(MyUntypedActor.class), "myactor"); // #system-actorOf try { new JavaTestKit(system) { { myActor.tell("hello", getRef()); expectMsgEquals("hello"); } }; } finally { JavaTestKit.shutdownActorSystem(system); } } @Test public void contextActorOf() { new JavaTestKit(system) { { // #context-actorOf class A extends UntypedActor { final ActorRef child = getContext().actorOf(Props.create(MyUntypedActor.class), "myChild"); // #plus-some-behavior @Override public void onReceive(Object msg) { getSender().tell(child, getSelf()); } // #plus-some-behavior } // #context-actorOf final ActorRef top = system.actorOf(Props.create(A.class, this)); top.tell("hello", getRef()); final ActorRef child = expectMsgClass(ActorRef.class); child.tell("hello", getRef()); expectMsgEquals("hello"); } }; } // this is just to make the test below a tiny fraction nicer private ActorSystem getContext() { return system; } static // #creating-indirectly class DependencyInjector implements IndirectActorProducer { final Object applicationContext; final String beanName; public DependencyInjector(Object applicationContext, String beanName) { this.applicationContext = applicationContext; this.beanName = beanName; } @Override public Class<? extends Actor> actorClass() { return MyActor.class; } @Override public MyActor produce() { MyActor result; // #obtain-fresh-Actor-instance-from-DI-framework result = new MyActor((String) applicationContext); // #obtain-fresh-Actor-instance-from-DI-framework return result; } } // #creating-indirectly @Test public void indirectActorOf() { final String applicationContext = "..."; // #creating-indirectly final ActorRef myActor = getContext() .actorOf( Props.create(DependencyInjector.class, applicationContext, "MyActor"), "myactor3"); // #creating-indirectly new JavaTestKit(system) { { myActor.tell("hello", getRef()); expectMsgEquals("..."); } }; } @SuppressWarnings("unused") @Test public void usingAsk() throws Exception { ActorRef myActor = system.actorOf(Props.create(MyAskActor.class, this), "myactor5"); // #using-ask Future<Object> future = Patterns.ask(myActor, "Hello", 1000); Object result = Await.result(future, Duration.create(1, TimeUnit.SECONDS)); // #using-ask } @Test public void receiveTimeout() { final ActorRef myActor = system.actorOf(Props.create(MyReceiveTimeoutUntypedActor.class)); new JavaTestKit(system) { { new Within( Duration.create(1, TimeUnit.SECONDS), Duration.create(1500, TimeUnit.MILLISECONDS)) { @Override protected void run() { myActor.tell("Hello", getRef()); expectMsgEquals("Hello world"); expectMsgEquals("timeout"); } }; } }; } @Test public void usePoisonPill() { final ActorRef myActor = system.actorOf(Props.create(MyUntypedActor.class)); new JavaTestKit(system) { { final ActorRef sender = getRef(); // #poison-pill myActor.tell(akka.actor.PoisonPill.getInstance(), sender); // #poison-pill watch(myActor); expectTerminated(myActor); } }; } @Test public void useKill() { new JavaTestKit(system) { { class Master extends UntypedActor { private SupervisorStrategy strategy = new OneForOneStrategy( -1, Duration.Undefined(), new Function<Throwable, Directive>() { @Override public Directive apply(Throwable thr) { if (thr instanceof ActorKilledException) { target.tell("killed", getSelf()); getContext().stop(getSelf()); return SupervisorStrategy.stop(); } return SupervisorStrategy.escalate(); } }); final ActorRef target; ActorRef child; // #preStart @Override public void preStart() { child = getContext().actorOf(Props.empty()); } // #preStart @SuppressWarnings("unused") public Master(ActorRef target) { this.target = target; /* * Only compilation of `forward` is verified here. */ final Object result = ""; // #forward target.forward(result, getContext()); // #forward } @Override public SupervisorStrategy supervisorStrategy() { return strategy; } // #reply @Override public void onReceive(Object msg) { Object result = // #calculate-result child; // #calculate-result // do not forget the second argument! getSender().tell(result, getSelf()); } // #reply // #postStop @Override public void postStop() { // #clean-up-resources-here final String message = "stopped"; // #tell // don’t forget to think about who is the sender (2nd argument) target.tell(message, getSelf()); // #tell // #clean-up-resources-here } // #postStop } final ActorRef master = system.actorOf(Props.create(Master.class, this, getRef())); expectMsgEquals(""); master.tell("", getRef()); final ActorRef victim = expectMsgClass(ActorRef.class); // #kill victim.tell(akka.actor.Kill.getInstance(), ActorRef.noSender()); // #kill expectMsgEquals("killed"); expectMsgEquals("stopped"); assert getLastSender().equals(master); } }; } @Test public void useBecome() { new JavaTestKit(system) { { ActorRef myActor = system.actorOf(Props.create(HotSwapActor.class)); myActor.tell("foo", getRef()); myActor.tell("bar", getRef()); expectMsgEquals("I am already happy :-)"); myActor.tell("bar", getRef()); expectMsgEquals("I am already happy :-)"); } }; } @Test public void useWatch() throws Exception { ActorRef myActor = system.actorOf(Props.create(WatchActor.class)); Future<Object> future = Patterns.ask(myActor, "kill", 1000); assert Await.result(future, Duration.create("1 second")).equals("finished"); } // compilation test only public void compileSelections() { // #selection-local // will look up this absolute path getContext().actorSelection("/user/serviceA/actor"); // will look up sibling beneath same supervisor getContext().actorSelection("../joe"); // #selection-local // #selection-wildcard // will look all children to serviceB with names starting with worker getContext().actorSelection("/user/serviceB/worker*"); // will look up all siblings beneath same supervisor getContext().actorSelection("../*"); // #selection-wildcard // #selection-remote getContext().actorSelection("akka.tcp://app@otherhost:1234/user/serviceB"); // #selection-remote } @Test public void useIdentify() throws Exception { new JavaTestKit(system) { { ActorRef a = system.actorOf(Props.create(MyUntypedActor.class), "another"); ActorRef b = system.actorOf(Props.create(Follower.class, getRef())); expectMsgEquals(a); system.stop(a); watch(b); expectTerminated(b); } }; } @Test public void usePatternsGracefulStop() throws Exception { ActorRef actorRef = system.actorOf(Props.create(Manager.class)); // #gracefulStop try { Future<Boolean> stopped = gracefulStop(actorRef, Duration.create(5, TimeUnit.SECONDS), Manager.SHUTDOWN); Await.result(stopped, Duration.create(6, TimeUnit.SECONDS)); // the actor has been stopped } catch (AskTimeoutException e) { // the actor wasn't stopped within 5 seconds } // #gracefulStop } class Result { final String x; final String s; public Result(String x, String s) { this.x = x; this.s = s; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((s == null) ? 0 : s.hashCode()); result = prime * result + ((x == null) ? 0 : x.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Result other = (Result) obj; if (s == null) { if (other.s != null) return false; } else if (!s.equals(other.s)) return false; if (x == null) { if (other.x != null) return false; } else if (!x.equals(other.x)) return false; return true; } } @Test public void usePatternsAskPipe() { new JavaTestKit(system) { { ActorRef actorA = system.actorOf(Props.create(MyUntypedActor.class)); ActorRef actorB = system.actorOf(Props.create(MyUntypedActor.class)); ActorRef actorC = getRef(); // #ask-pipe final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS)); final ArrayList<Future<Object>> futures = new ArrayList<Future<Object>>(); futures.add(ask(actorA, "request", 1000)); // using 1000ms timeout futures.add(ask(actorB, "another request", t)); // using timeout from // above final Future<Iterable<Object>> aggregate = Futures.sequence(futures, system.dispatcher()); final Future<Result> transformed = aggregate.map( new Mapper<Iterable<Object>, Result>() { public Result apply(Iterable<Object> coll) { final Iterator<Object> it = coll.iterator(); final String x = (String) it.next(); final String s = (String) it.next(); return new Result(x, s); } }, system.dispatcher()); pipe(transformed, system.dispatcher()).to(actorC); // #ask-pipe expectMsgEquals(new Result("request", "another request")); } }; } public // #props-factory static class DemoActor extends UntypedActor { /** * Create Props for an actor of this type. * * @param magicNumber The magic number to be passed to this actor’s constructor. * @return a Props for creating this actor, which can then be further configured (e.g. calling * `.withDispatcher()` on it) */ public static Props props(final int magicNumber) { return Props.create( new Creator<DemoActor>() { private static final long serialVersionUID = 1L; @Override public DemoActor create() throws Exception { return new DemoActor(magicNumber); } }); } final int magicNumber; public DemoActor(int magicNumber) { this.magicNumber = magicNumber; } @Override public void onReceive(Object msg) { // some behavior here } } // #props-factory @Test public void demoActor() { // #props-factory system.actorOf(DemoActor.props(42), "demo"); // #props-factory } public static class MyActor extends UntypedActor { final String s; public MyActor(String s) { this.s = s; } public void onReceive(Object message) { getSender().tell(s, getSelf()); } /* * This section must be kept in sync with the actual Actor trait. * * BOYSCOUT RULE: whenever you read this, verify that! */ // #lifecycle-callbacks public void preStart() {} public void preRestart(Throwable reason, scala.Option<Object> message) { for (ActorRef each : getContext().getChildren()) { getContext().unwatch(each); getContext().stop(each); } postStop(); } public void postRestart(Throwable reason) { preStart(); } public void postStop() {} // #lifecycle-callbacks } public class MyAskActor extends UntypedActor { public void onReceive(Object message) throws Exception { // #reply-exception try { String result = operation(); getSender().tell(result, getSelf()); } catch (Exception e) { getSender().tell(new akka.actor.Status.Failure(e), getSelf()); throw e; } // #reply-exception } private String operation() { return "Hi"; } } public // #gracefulStop-actor static class Manager extends UntypedActor { public static final String SHUTDOWN = "shutdown"; ActorRef worker = getContext().watch(getContext().actorOf(Props.create(Cruncher.class), "worker")); public void onReceive(Object message) { if (message.equals("job")) { worker.tell("crunch", getSelf()); } else if (message.equals(SHUTDOWN)) { worker.tell(PoisonPill.getInstance(), getSelf()); getContext().become(shuttingDown); } } Procedure<Object> shuttingDown = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals("job")) { getSender().tell("service unavailable, shutting down", getSelf()); } else if (message instanceof Terminated) { getContext().stop(getSelf()); } } }; } // #gracefulStop-actor static class Cruncher extends UntypedActor { public void onReceive(Object message) { // crunch... } } public // #hot-swap-actor static class HotSwapActor extends UntypedActor { Procedure<Object> angry = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals("bar")) { getSender().tell("I am already angry?", getSelf()); } else if (message.equals("foo")) { getContext().become(happy); } } }; Procedure<Object> happy = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals("bar")) { getSender().tell("I am already happy :-)", getSelf()); } else if (message.equals("foo")) { getContext().become(angry); } } }; public void onReceive(Object message) { if (message.equals("bar")) { getContext().become(angry); } else if (message.equals("foo")) { getContext().become(happy); } else { unhandled(message); } } } // #hot-swap-actor public // #stash static class ActorWithProtocol extends UntypedActorWithStash { public void onReceive(Object msg) { if (msg.equals("open")) { unstashAll(); getContext() .become( new Procedure<Object>() { public void apply(Object msg) throws Exception { if (msg.equals("write")) { // do writing... } else if (msg.equals("close")) { unstashAll(); getContext().unbecome(); } else { stash(); } } }, false); // add behavior on top instead of replacing } else { stash(); } } } // #stash public // #watch static class WatchActor extends UntypedActor { final ActorRef child = this.getContext().actorOf(Props.empty(), "child"); { this.getContext().watch(child); // <-- the only call needed for registration } ActorRef lastSender = getContext().system().deadLetters(); @Override public void onReceive(Object message) { if (message.equals("kill")) { getContext().stop(child); lastSender = getSender(); } else if (message instanceof Terminated) { final Terminated t = (Terminated) message; if (t.getActor() == child) { lastSender.tell("finished", getSelf()); } } else { unhandled(message); } } } // #watch public // #identify static class Follower extends UntypedActor { final String identifyId = "1"; { ActorSelection selection = getContext().actorSelection("/user/another"); selection.tell(new Identify(identifyId), getSelf()); } ActorRef another; // #test-omitted final ActorRef probe; public Follower(ActorRef probe) { this.probe = probe; } // #test-omitted @Override public void onReceive(Object message) { if (message instanceof ActorIdentity) { ActorIdentity identity = (ActorIdentity) message; if (identity.correlationId().equals(identifyId)) { ActorRef ref = identity.getRef(); if (ref == null) getContext().stop(getSelf()); else { another = ref; getContext().watch(another); // #test-omitted probe.tell(ref, getSelf()); // #test-omitted } } } else if (message instanceof Terminated) { final Terminated t = (Terminated) message; if (t.getActor().equals(another)) { getContext().stop(getSelf()); } } else { unhandled(message); } } } // #identify }