ActorContext.getParent for Java API #22413
This commit is contained in:
parent
5ff44194a3
commit
2eb226ed32
213 changed files with 1319 additions and 1523 deletions
325
akka-docs/rst/java/code/jdocs/event/EventBusDocTest.java
Normal file
325
akka-docs/rst/java/code/jdocs/event/EventBusDocTest.java
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
package jdocs.event;
|
||||
|
||||
import akka.event.japi.EventBus;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import jdocs.AbstractJavaTest;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
|
||||
import akka.actor.ActorSystem;
|
||||
import akka.actor.ActorRef;
|
||||
import akka.testkit.AkkaJUnitActorSystemResource;
|
||||
import akka.testkit.JavaTestKit;
|
||||
import akka.util.Subclassification;
|
||||
import scala.concurrent.duration.FiniteDuration;
|
||||
|
||||
//#lookup-bus
|
||||
import akka.event.japi.LookupEventBus;
|
||||
|
||||
//#lookup-bus
|
||||
|
||||
//#subchannel-bus
|
||||
import akka.event.japi.SubchannelEventBus;
|
||||
|
||||
//#subchannel-bus
|
||||
|
||||
//#scanning-bus
|
||||
import akka.event.japi.ScanningEventBus;
|
||||
|
||||
//#scanning-bus
|
||||
|
||||
//#actor-bus
|
||||
import akka.event.japi.ManagedActorEventBus;
|
||||
|
||||
//#actor-bus
|
||||
|
||||
public class EventBusDocTest extends AbstractJavaTest {
|
||||
|
||||
public static class Event {}
|
||||
public static class Subscriber {}
|
||||
public static class Classifier {}
|
||||
|
||||
static public interface EventBusApi extends EventBus<Event, Subscriber, Classifier> {
|
||||
|
||||
@Override
|
||||
//#event-bus-api
|
||||
/**
|
||||
* Attempts to register the subscriber to the specified Classifier
|
||||
* @return true if successful and false if not (because it was already
|
||||
* subscribed to that Classifier, or otherwise)
|
||||
*/
|
||||
public boolean subscribe(Subscriber subscriber, Classifier to);
|
||||
|
||||
//#event-bus-api
|
||||
|
||||
@Override
|
||||
//#event-bus-api
|
||||
/**
|
||||
* Attempts to deregister the subscriber from the specified Classifier
|
||||
* @return true if successful and false if not (because it wasn't subscribed
|
||||
* to that Classifier, or otherwise)
|
||||
*/
|
||||
public boolean unsubscribe(Subscriber subscriber, Classifier from);
|
||||
|
||||
//#event-bus-api
|
||||
|
||||
@Override
|
||||
//#event-bus-api
|
||||
/**
|
||||
* Attempts to deregister the subscriber from all Classifiers it may be subscribed to
|
||||
*/
|
||||
public void unsubscribe(Subscriber subscriber);
|
||||
|
||||
//#event-bus-api
|
||||
|
||||
@Override
|
||||
//#event-bus-api
|
||||
/**
|
||||
* Publishes the specified Event to this bus
|
||||
*/
|
||||
public void publish(Event event);
|
||||
|
||||
//#event-bus-api
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
//#lookup-bus
|
||||
public class MsgEnvelope {
|
||||
public final String topic;
|
||||
public final Object payload;
|
||||
|
||||
public MsgEnvelope(String topic, Object payload) {
|
||||
this.topic = topic;
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
||||
|
||||
//#lookup-bus
|
||||
static
|
||||
//#lookup-bus
|
||||
/**
|
||||
* Publishes the payload of the MsgEnvelope when the topic of the
|
||||
* MsgEnvelope equals the String specified when subscribing.
|
||||
*/
|
||||
public class LookupBusImpl extends LookupEventBus<MsgEnvelope, ActorRef, String> {
|
||||
|
||||
// is used for extracting the classifier from the incoming events
|
||||
@Override public String classify(MsgEnvelope event) {
|
||||
return event.topic;
|
||||
}
|
||||
|
||||
// will be invoked for each event for all subscribers which registered themselves
|
||||
// for the event’s classifier
|
||||
@Override public void publish(MsgEnvelope event, ActorRef subscriber) {
|
||||
subscriber.tell(event.payload, ActorRef.noSender());
|
||||
}
|
||||
|
||||
// must define a full order over the subscribers, expressed as expected from
|
||||
// `java.lang.Comparable.compare`
|
||||
@Override public int compareSubscribers(ActorRef a, ActorRef b) {
|
||||
return a.compareTo(b);
|
||||
}
|
||||
|
||||
// determines the initial size of the index data structure
|
||||
// used internally (i.e. the expected number of different classifiers)
|
||||
@Override public int mapSize() {
|
||||
return 128;
|
||||
}
|
||||
|
||||
}
|
||||
//#lookup-bus
|
||||
|
||||
static
|
||||
//#subchannel-bus
|
||||
public class StartsWithSubclassification implements Subclassification<String> {
|
||||
@Override public boolean isEqual(String x, String y) {
|
||||
return x.equals(y);
|
||||
}
|
||||
|
||||
@Override public boolean isSubclass(String x, String y) {
|
||||
return x.startsWith(y);
|
||||
}
|
||||
}
|
||||
|
||||
//#subchannel-bus
|
||||
|
||||
static
|
||||
//#subchannel-bus
|
||||
/**
|
||||
* Publishes the payload of the MsgEnvelope when the topic of the
|
||||
* MsgEnvelope starts with the String specified when subscribing.
|
||||
*/
|
||||
public class SubchannelBusImpl extends SubchannelEventBus<MsgEnvelope, ActorRef, String> {
|
||||
|
||||
// Subclassification is an object providing `isEqual` and `isSubclass`
|
||||
// to be consumed by the other methods of this classifier
|
||||
@Override public Subclassification<String> subclassification() {
|
||||
return new StartsWithSubclassification();
|
||||
}
|
||||
|
||||
// is used for extracting the classifier from the incoming events
|
||||
@Override public String classify(MsgEnvelope event) {
|
||||
return event.topic;
|
||||
}
|
||||
|
||||
// will be invoked for each event for all subscribers which registered themselves
|
||||
// for the event’s classifier
|
||||
@Override public void publish(MsgEnvelope event, ActorRef subscriber) {
|
||||
subscriber.tell(event.payload, ActorRef.noSender());
|
||||
}
|
||||
|
||||
}
|
||||
//#subchannel-bus
|
||||
|
||||
static
|
||||
//#scanning-bus
|
||||
/**
|
||||
* Publishes String messages with length less than or equal to the length
|
||||
* specified when subscribing.
|
||||
*/
|
||||
public class ScanningBusImpl extends ScanningEventBus<String, ActorRef, Integer> {
|
||||
|
||||
// is needed for determining matching classifiers and storing them in an
|
||||
// ordered collection
|
||||
@Override public int compareClassifiers(Integer a, Integer b) {
|
||||
return a.compareTo(b);
|
||||
}
|
||||
|
||||
// is needed for storing subscribers in an ordered collection
|
||||
@Override public int compareSubscribers(ActorRef a, ActorRef b) {
|
||||
return a.compareTo(b);
|
||||
}
|
||||
|
||||
// determines whether a given classifier shall match a given event; it is invoked
|
||||
// for each subscription for all received events, hence the name of the classifier
|
||||
@Override public boolean matches(Integer classifier, String event) {
|
||||
return event.length() <= classifier;
|
||||
}
|
||||
|
||||
// will be invoked for each event for all subscribers which registered themselves
|
||||
// for the event’s classifier
|
||||
@Override public void publish(String event, ActorRef subscriber) {
|
||||
subscriber.tell(event, ActorRef.noSender());
|
||||
}
|
||||
|
||||
}
|
||||
//#scanning-bus
|
||||
|
||||
static
|
||||
//#actor-bus
|
||||
public class Notification {
|
||||
public final ActorRef ref;
|
||||
public final int id;
|
||||
|
||||
public Notification(ActorRef ref, int id) {
|
||||
this.ref = ref;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
//#actor-bus
|
||||
|
||||
static
|
||||
//#actor-bus
|
||||
public class ActorBusImpl extends ManagedActorEventBus<Notification> {
|
||||
|
||||
// the ActorSystem will be used for book-keeping operations, such as subscribers terminating
|
||||
public ActorBusImpl(ActorSystem system) {
|
||||
super(system);
|
||||
}
|
||||
|
||||
// is used for extracting the classifier from the incoming events
|
||||
@Override public ActorRef classify(Notification event) {
|
||||
return event.ref;
|
||||
}
|
||||
|
||||
// determines the initial size of the index data structure
|
||||
// used internally (i.e. the expected number of different classifiers)
|
||||
@Override public int mapSize() {
|
||||
return 128;
|
||||
}
|
||||
|
||||
}
|
||||
//#actor-bus
|
||||
|
||||
@ClassRule
|
||||
public static AkkaJUnitActorSystemResource actorSystemResource =
|
||||
new AkkaJUnitActorSystemResource("EventBusDocTest");
|
||||
|
||||
private final ActorSystem system = actorSystemResource.getSystem();
|
||||
|
||||
@Test
|
||||
public void demonstrateLookupClassification() {
|
||||
new JavaTestKit(system) {{
|
||||
//#lookup-bus-test
|
||||
LookupBusImpl lookupBus = new LookupBusImpl();
|
||||
lookupBus.subscribe(getTestActor(), "greetings");
|
||||
lookupBus.publish(new MsgEnvelope("time", System.currentTimeMillis()));
|
||||
lookupBus.publish(new MsgEnvelope("greetings", "hello"));
|
||||
expectMsgEquals("hello");
|
||||
//#lookup-bus-test
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void demonstrateSubchannelClassification() {
|
||||
new JavaTestKit(system) {{
|
||||
//#subchannel-bus-test
|
||||
SubchannelBusImpl subchannelBus = new SubchannelBusImpl();
|
||||
subchannelBus.subscribe(getTestActor(), "abc");
|
||||
subchannelBus.publish(new MsgEnvelope("xyzabc", "x"));
|
||||
subchannelBus.publish(new MsgEnvelope("bcdef", "b"));
|
||||
subchannelBus.publish(new MsgEnvelope("abc", "c"));
|
||||
expectMsgEquals("c");
|
||||
subchannelBus.publish(new MsgEnvelope("abcdef", "d"));
|
||||
expectMsgEquals("d");
|
||||
//#subchannel-bus-test
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void demonstrateScanningClassification() {
|
||||
new JavaTestKit(system) {{
|
||||
//#scanning-bus-test
|
||||
ScanningBusImpl scanningBus = new ScanningBusImpl();
|
||||
scanningBus.subscribe(getTestActor(), 3);
|
||||
scanningBus.publish("xyzabc");
|
||||
scanningBus.publish("ab");
|
||||
expectMsgEquals("ab");
|
||||
scanningBus.publish("abc");
|
||||
expectMsgEquals("abc");
|
||||
//#scanning-bus-test
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void demonstrateManagedActorClassification() {
|
||||
//#actor-bus-test
|
||||
ActorRef observer1 = new JavaTestKit(system).getRef();
|
||||
ActorRef observer2 = new JavaTestKit(system).getRef();
|
||||
JavaTestKit probe1 = new JavaTestKit(system);
|
||||
JavaTestKit probe2 = new JavaTestKit(system);
|
||||
ActorRef subscriber1 = probe1.getRef();
|
||||
ActorRef subscriber2 = probe2.getRef();
|
||||
ActorBusImpl actorBus = new ActorBusImpl(system);
|
||||
actorBus.subscribe(subscriber1, observer1);
|
||||
actorBus.subscribe(subscriber2, observer1);
|
||||
actorBus.subscribe(subscriber2, observer2);
|
||||
Notification n1 = new Notification(observer1, 100);
|
||||
actorBus.publish(n1);
|
||||
probe1.expectMsgEquals(n1);
|
||||
probe2.expectMsgEquals(n1);
|
||||
Notification n2 = new Notification(observer2, 101);
|
||||
actorBus.publish(n2);
|
||||
probe2.expectMsgEquals(n2);
|
||||
probe1.expectNoMsg(FiniteDuration.create(500, TimeUnit.MILLISECONDS));
|
||||
//#actor-bus-test
|
||||
}
|
||||
|
||||
}
|
||||
245
akka-docs/rst/java/code/jdocs/event/LoggingDocTest.java
Normal file
245
akka-docs/rst/java/code/jdocs/event/LoggingDocTest.java
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
package jdocs.event;
|
||||
|
||||
//#imports
|
||||
import akka.actor.*;
|
||||
import akka.event.Logging;
|
||||
import akka.event.LoggingAdapter;
|
||||
|
||||
//#imports
|
||||
|
||||
//#imports-listener
|
||||
import akka.event.Logging.InitializeLogger;
|
||||
import akka.event.Logging.Error;
|
||||
import akka.event.Logging.Warning;
|
||||
import akka.event.Logging.Info;
|
||||
import akka.event.Logging.Debug;
|
||||
|
||||
//#imports-listener
|
||||
|
||||
import jdocs.AbstractJavaTest;
|
||||
import org.junit.Test;
|
||||
import akka.testkit.JavaTestKit;
|
||||
import java.util.Optional;
|
||||
|
||||
//#imports-mdc
|
||||
import akka.event.DiagnosticLoggingAdapter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
//#imports-mdc
|
||||
|
||||
//#imports-deadletter
|
||||
import akka.actor.ActorRef;
|
||||
import akka.actor.ActorSystem;
|
||||
//#imports-deadletter
|
||||
|
||||
public class LoggingDocTest extends AbstractJavaTest {
|
||||
|
||||
@Test
|
||||
public void useLoggingActor() {
|
||||
ActorSystem system = ActorSystem.create("MySystem");
|
||||
ActorRef myActor = system.actorOf(Props.create(MyActor.class, this));
|
||||
myActor.tell("test", ActorRef.noSender());
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useLoggingActorWithMDC() {
|
||||
ActorSystem system = ActorSystem.create("MyDiagnosticSystem");
|
||||
ActorRef mdcActor = system.actorOf(Props.create(MdcActor.class, this));
|
||||
mdcActor.tell("some request", ActorRef.noSender());
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subscribeToDeadLetters() {
|
||||
//#deadletters
|
||||
final ActorSystem system = ActorSystem.create("DeadLetters");
|
||||
final ActorRef actor = system.actorOf(Props.create(DeadLetterActor.class));
|
||||
system.eventStream().subscribe(actor, DeadLetter.class);
|
||||
//#deadletters
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
}
|
||||
|
||||
//#superclass-subscription-eventstream
|
||||
interface AllKindsOfMusic { }
|
||||
|
||||
class Jazz implements AllKindsOfMusic {
|
||||
final public String artist;
|
||||
public Jazz(String artist) {
|
||||
this.artist = artist;
|
||||
}
|
||||
}
|
||||
class Electronic implements AllKindsOfMusic {
|
||||
final public String artist;
|
||||
public Electronic(String artist) {
|
||||
this.artist = artist;
|
||||
}
|
||||
}
|
||||
|
||||
static class Listener extends AbstractActor {
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.match(Jazz.class, msg ->
|
||||
System.out.printf("%s is listening to: %s%n", getSelf().path().name(), msg)
|
||||
)
|
||||
.match(Electronic.class, msg ->
|
||||
System.out.printf("%s is listening to: %s%n", getSelf().path().name(), msg)
|
||||
)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//#superclass-subscription-eventstream
|
||||
|
||||
@Test
|
||||
public void subscribeBySubclassification() {
|
||||
final ActorSystem system = ActorSystem.create("DeadLetters");
|
||||
//#superclass-subscription-eventstream
|
||||
final ActorRef actor = system.actorOf(Props.create(DeadLetterActor.class));
|
||||
system.eventStream().subscribe(actor, DeadLetter.class);
|
||||
|
||||
final ActorRef jazzListener = system.actorOf(Props.create(Listener.class));
|
||||
final ActorRef musicListener = system.actorOf(Props.create(Listener.class));
|
||||
system.eventStream().subscribe(jazzListener, Jazz.class);
|
||||
system.eventStream().subscribe(musicListener, AllKindsOfMusic.class);
|
||||
|
||||
// only musicListener gets this message, since it listens to *all* kinds of music:
|
||||
system.eventStream().publish(new Electronic("Parov Stelar"));
|
||||
|
||||
// jazzListener and musicListener will be notified about Jazz:
|
||||
system.eventStream().publish(new Jazz("Sonny Rollins"));
|
||||
|
||||
//#superclass-subscription-eventstream
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subscribeToSuppressedDeadLetters() {
|
||||
final ActorSystem system = ActorSystem.create("SuppressedDeadLetters");
|
||||
final ActorRef actor = system.actorOf(Props.create(DeadLetterActor.class));
|
||||
|
||||
//#suppressed-deadletters
|
||||
system.eventStream().subscribe(actor, SuppressedDeadLetter.class);
|
||||
//#suppressed-deadletters
|
||||
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
}
|
||||
@Test
|
||||
public void subscribeToAllDeadLetters() {
|
||||
final ActorSystem system = ActorSystem.create("AllDeadLetters");
|
||||
final ActorRef actor = system.actorOf(Props.create(DeadLetterActor.class));
|
||||
|
||||
//#all-deadletters
|
||||
system.eventStream().subscribe(actor, AllDeadLetters.class);
|
||||
//#all-deadletters
|
||||
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void demonstrateMultipleArgs() {
|
||||
final ActorSystem system = ActorSystem.create("multiArg");
|
||||
//#array
|
||||
final Object[] args = new Object[] { "The", "brown", "fox", "jumps", 42 };
|
||||
system.log().debug("five parameters: {}, {}, {}, {}, {}", args);
|
||||
//#array
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
}
|
||||
|
||||
//#my-actor
|
||||
class MyActor extends AbstractActor {
|
||||
LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
|
||||
|
||||
@Override
|
||||
public void preStart() {
|
||||
log.debug("Starting");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRestart(Throwable reason, Optional<Object> message) {
|
||||
log.error(reason, "Restarting due to [{}] when processing [{}]",
|
||||
reason.getMessage(), message.isPresent() ? message.get() : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.matchEquals("test", msg ->
|
||||
log.info("Received test")
|
||||
)
|
||||
.matchAny(msg ->
|
||||
log.warning("Received unknown message: {}", msg)
|
||||
)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
//#my-actor
|
||||
|
||||
//#mdc-actor
|
||||
class MdcActor extends AbstractActor {
|
||||
|
||||
final DiagnosticLoggingAdapter log = Logging.getLogger(this);
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.matchAny(msg -> {
|
||||
Map<String, Object> mdc;
|
||||
mdc = new HashMap<String, Object>();
|
||||
mdc.put("requestId", 1234);
|
||||
mdc.put("visitorId", 5678);
|
||||
log.setMDC(mdc);
|
||||
|
||||
log.info("Starting new request");
|
||||
|
||||
log.clearMDC();
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
//#mdc-actor
|
||||
|
||||
//#my-event-listener
|
||||
class MyEventListener extends AbstractActor {
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.match(InitializeLogger.class, msg -> {
|
||||
getSender().tell(Logging.loggerInitialized(), getSelf());
|
||||
})
|
||||
.match(Error.class, msg -> {
|
||||
// ...
|
||||
})
|
||||
.match(Warning.class, msg -> {
|
||||
// ...
|
||||
})
|
||||
.match(Info.class, msg -> {
|
||||
// ...
|
||||
})
|
||||
.match(Debug.class, msg -> {
|
||||
// ...
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//#my-event-listener
|
||||
|
||||
static
|
||||
//#deadletter-actor
|
||||
public class DeadLetterActor extends AbstractActor {
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.match(DeadLetter.class, msg -> {
|
||||
System.out.println(msg);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//#deadletter-actor
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue