diff --git a/akka-active-object-test/pom.xml b/akka-active-object-test/pom.xml index dffacd8db0..e498c34d32 100644 --- a/akka-active-object-test/pom.xml +++ b/akka-active-object-test/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - Akka Active Object Tests in Java + Akka TypedActor Tests in Java akka-active-object-test se.scalablesolutions.akka 0.9 diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/AllTest.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/AllTest.java index 465c9da182..77739f6ff1 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/AllTest.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/AllTest.java @@ -10,7 +10,7 @@ public class AllTest extends TestCase { suite.addTestSuite(InMemoryStateTest.class); suite.addTestSuite(InMemNestedStateTest.class); suite.addTestSuite(RemoteInMemoryStateTest.class); - suite.addTestSuite(ActiveObjectGuiceConfiguratorTest.class); + suite.addTestSuite(TypedActorGuiceConfiguratorTest.class); return suite; } diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java index 746df950bf..db9d4d4146 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java @@ -6,7 +6,7 @@ package se.scalablesolutions.akka.api; import se.scalablesolutions.akka.config.*; import se.scalablesolutions.akka.config.Config; -import se.scalablesolutions.akka.config.ActiveObjectConfigurator; +import se.scalablesolutions.akka.config.TypedActorConfigurator; import static se.scalablesolutions.akka.config.JavaConfig.*; import se.scalablesolutions.akka.actor.*; import junit.framework.TestCase; @@ -14,7 +14,7 @@ import junit.framework.TestCase; public class InMemNestedStateTest extends TestCase { static String messageLog = ""; - final private ActiveObjectConfigurator conf = new ActiveObjectConfigurator(); + final private TypedActorConfigurator conf = new TypedActorConfigurator(); public InMemNestedStateTest() { conf.configure( diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java index 3708d58acc..6562d0d611 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java @@ -8,7 +8,7 @@ import junit.framework.TestCase; import se.scalablesolutions.akka.config.Config; import se.scalablesolutions.akka.config.*; -import se.scalablesolutions.akka.config.ActiveObjectConfigurator; +import se.scalablesolutions.akka.config.TypedActorConfigurator; import static se.scalablesolutions.akka.config.JavaConfig.*; @@ -17,7 +17,7 @@ import se.scalablesolutions.akka.actor.*; public class InMemoryStateTest extends TestCase { static String messageLog = ""; - final private ActiveObjectConfigurator conf = new ActiveObjectConfigurator(); + final private TypedActorConfigurator conf = new TypedActorConfigurator(); public InMemoryStateTest() { Config.config(); diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/MiscActiveObjectTest.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/MiscActiveObjectTest.java index e61b8ac07d..aaa97d3587 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/MiscActiveObjectTest.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/MiscActiveObjectTest.java @@ -1,7 +1,7 @@ package se.scalablesolutions.akka.api; -import static se.scalablesolutions.akka.actor.ActiveObject.link; -import static se.scalablesolutions.akka.actor.ActiveObject.newInstance; +import static se.scalablesolutions.akka.actor.TypedActor.link; +import static se.scalablesolutions.akka.actor.TypedActor.newInstance; import org.junit.Assert; import org.junit.Test; @@ -15,7 +15,7 @@ import junit.framework.TestCase; * @author johanrask * */ -public class MiscActiveObjectTest extends TestCase { +public class MiscTypedActorTest extends TestCase { /** diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java index d4b4fd7687..3ae8b647ab 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java @@ -5,8 +5,8 @@ package se.scalablesolutions.akka.api; import se.scalablesolutions.akka.config.Config; -import se.scalablesolutions.akka.actor.ActiveObject; -import se.scalablesolutions.akka.config.ActiveObjectConfigurator; +import se.scalablesolutions.akka.actor.TypedActor; +import se.scalablesolutions.akka.config.TypedActorConfigurator; import se.scalablesolutions.akka.remote.RemoteNode; import junit.framework.TestCase; @@ -23,14 +23,14 @@ public class RemoteInMemoryStateTest extends TestCase { try { Thread.currentThread().sleep(1000); } catch (Exception e) {} Config.config(); } - final ActiveObjectConfigurator conf = new ActiveObjectConfigurator(); + final TypedActorConfigurator conf = new TypedActorConfigurator(); protected void tearDown() { conf.stop(); } public void testMapShouldNotRollbackStateForStatefulServerInCaseOfSuccess() { - InMemStateful stateful = ActiveObject.newRemoteInstance(InMemStateful.class, 1000, "localhost", 9999); + InMemStateful stateful = TypedActor.newRemoteInstance(InMemStateful.class, 1000, "localhost", 9999); stateful.init(); stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init"); // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactionrequired @@ -38,10 +38,10 @@ public class RemoteInMemoryStateTest extends TestCase { } public void testMapShouldRollbackStateForStatefulServerInCaseOfFailure() { - InMemStateful stateful = ActiveObject.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); + InMemStateful stateful = TypedActor.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); stateful.init(); stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init"); // set init state - InMemFailer failer = ActiveObject.newRemoteInstance(InMemFailer.class, 1000, "localhost", 9999); //conf.getInstance(InMemFailer.class); + InMemFailer failer = TypedActor.newRemoteInstance(InMemFailer.class, 1000, "localhost", 9999); //conf.getInstance(InMemFailer.class); try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactionrequired method fail("should have thrown an exception"); @@ -51,7 +51,7 @@ public class RemoteInMemoryStateTest extends TestCase { } public void testVectorShouldNotRollbackStateForStatefulServerInCaseOfSuccess() { - InMemStateful stateful = ActiveObject.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); + InMemStateful stateful = TypedActor.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); stateful.init(); stateful.setVectorState("init"); // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactionrequired @@ -59,10 +59,10 @@ public class RemoteInMemoryStateTest extends TestCase { } public void testVectorShouldRollbackStateForStatefulServerInCaseOfFailure() { - InMemStateful stateful = ActiveObject.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); + InMemStateful stateful = TypedActor.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); stateful.init(); stateful.setVectorState("init"); // set init state - InMemFailer failer = ActiveObject.newRemoteInstance(InMemFailer.class, 10000, "localhost", 9999); //conf.getInstance(InMemFailer.class); + InMemFailer failer = TypedActor.newRemoteInstance(InMemFailer.class, 10000, "localhost", 9999); //conf.getInstance(InMemFailer.class); try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactionrequired method fail("should have thrown an exception"); @@ -72,7 +72,7 @@ public class RemoteInMemoryStateTest extends TestCase { } public void testRefShouldNotRollbackStateForStatefulServerInCaseOfSuccess() { - InMemStateful stateful = ActiveObject.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); + InMemStateful stateful = TypedActor.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); stateful.init(); stateful.setRefState("init"); // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactionrequired @@ -80,10 +80,10 @@ public class RemoteInMemoryStateTest extends TestCase { } public void testRefShouldRollbackStateForStatefulServerInCaseOfFailure() { - InMemStateful stateful = ActiveObject.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); + InMemStateful stateful = TypedActor.newRemoteInstance(InMemStateful.class, 10000, "localhost", 9999); stateful.init(); stateful.setRefState("init"); // set init state - InMemFailer failer = ActiveObject.newRemoteInstance(InMemFailer.class, 10000, "localhost", 9999); //conf.getInstance(InMemFailer.class); + InMemFailer failer = TypedActor.newRemoteInstance(InMemFailer.class, 10000, "localhost", 9999); //conf.getInstance(InMemFailer.class); try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactionrequired method fail("should have thrown an exception"); diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/ActiveObjectGuiceConfiguratorTest.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/TypedActorGuiceConfiguratorTest.java similarity index 87% rename from akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/ActiveObjectGuiceConfiguratorTest.java rename to akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/TypedActorGuiceConfiguratorTest.java index 69f74ec537..e604b4da69 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/ActiveObjectGuiceConfiguratorTest.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/TypedActorGuiceConfiguratorTest.java @@ -10,14 +10,14 @@ import com.google.inject.Scopes; import junit.framework.TestCase; import se.scalablesolutions.akka.config.Config; -import se.scalablesolutions.akka.config.ActiveObjectConfigurator; +import se.scalablesolutions.akka.config.TypedActorConfigurator; import static se.scalablesolutions.akka.config.JavaConfig.*; import se.scalablesolutions.akka.dispatch.*; -public class ActiveObjectGuiceConfiguratorTest extends TestCase { +public class TypedActorGuiceConfiguratorTest extends TestCase { static String messageLog = ""; - final private ActiveObjectConfigurator conf = new ActiveObjectConfigurator(); + final private TypedActorConfigurator conf = new TypedActorConfigurator(); protected void setUp() { Config.config(); @@ -46,7 +46,7 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase { } - public void testGuiceActiveObjectInjection() { + public void testGuiceTypedActorInjection() { messageLog = ""; Foo foo = conf.getInstance(Foo.class); Bar bar = conf.getInstance(Bar.class); @@ -69,7 +69,7 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase { } } - public void testActiveObjectInvocation() throws InterruptedException { + public void testTypedActorInvocation() throws InterruptedException { messageLog = ""; Foo foo = conf.getInstance(Foo.class); messageLog += foo.foo("foo "); @@ -79,7 +79,7 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase { assertEquals("foo return_foo before_bar ", messageLog); } - public void testActiveObjectInvocationsInvocation() throws InterruptedException { + public void testTypedActorInvocationsInvocation() throws InterruptedException { messageLog = ""; Foo foo = conf.getInstance(Foo.class); Bar bar = conf.getInstance(Bar.class); diff --git a/akka-camel/src/main/resources/META-INF/services/org/apache/camel/component/active-object b/akka-camel/src/main/resources/META-INF/services/org/apache/camel/component/active-object index 5dd88a0671..e004d887b3 100644 --- a/akka-camel/src/main/resources/META-INF/services/org/apache/camel/component/active-object +++ b/akka-camel/src/main/resources/META-INF/services/org/apache/camel/component/active-object @@ -1 +1 @@ -class=se.scalablesolutions.akka.camel.component.ActiveObjectComponent \ No newline at end of file +class=se.scalablesolutions.akka.camel.component.TypedActorComponent \ No newline at end of file diff --git a/akka-camel/src/main/scala/CamelContextLifecycle.scala b/akka-camel/src/main/scala/CamelContextLifecycle.scala index 640ba14e36..d1683a9464 100644 --- a/akka-camel/src/main/scala/CamelContextLifecycle.scala +++ b/akka-camel/src/main/scala/CamelContextLifecycle.scala @@ -9,7 +9,7 @@ import java.util.Map import org.apache.camel.{ProducerTemplate, CamelContext} import org.apache.camel.impl.DefaultCamelContext -import se.scalablesolutions.akka.camel.component.ActiveObjectComponent +import se.scalablesolutions.akka.camel.component.TypedActorComponent import se.scalablesolutions.akka.util.Logging /** @@ -29,13 +29,13 @@ trait CamelContextLifecycle extends Logging { private var _started = false /** - * Camel component for accessing active objects. + * Camel component for accessing typed actors. */ - private[camel] var activeObjectComponent: ActiveObjectComponent = _ + private[camel] var activeObjectComponent: TypedActorComponent = _ /** - * Registry in which active objects are TEMPORARILY registered during - * creation of Camel routes to active objects. + * Registry in which typed actors are TEMPORARILY registered during + * creation of Camel routes to typed actors. */ private[camel] var activeObjectRegistry: Map[String, AnyRef] = _ @@ -93,15 +93,15 @@ trait CamelContextLifecycle extends Logging { * CamelContext stream-caching is enabled. If applications want to disable stream- * caching they can do so after this method returned and prior to calling start. * This method also registers a new - * {@link se.scalablesolutions.akka.camel.component.ActiveObjectComponent} at - * context under a name defined by ActiveObjectComponent.InternalSchema. + * {@link se.scalablesolutions.akka.camel.component.TypedActorComponent} at + * context under a name defined by TypedActorComponent.InternalSchema. */ def init(context: CamelContext) { - this.activeObjectComponent = new ActiveObjectComponent + this.activeObjectComponent = new TypedActorComponent this.activeObjectRegistry = activeObjectComponent.activeObjectRegistry this.context = context this.context.setStreamCaching(true) - this.context.addComponent(ActiveObjectComponent.InternalSchema, activeObjectComponent) + this.context.addComponent(TypedActorComponent.InternalSchema, activeObjectComponent) this.template = context.createProducerTemplate _initialized = true log.info("Camel context initialized") diff --git a/akka-camel/src/main/scala/CamelService.scala b/akka-camel/src/main/scala/CamelService.scala index 11f2907c4d..0fbbceee2e 100644 --- a/akka-camel/src/main/scala/CamelService.scala +++ b/akka-camel/src/main/scala/CamelService.scala @@ -10,7 +10,7 @@ import se.scalablesolutions.akka.actor.{AspectInitRegistry, ActorRegistry} import se.scalablesolutions.akka.util.{Bootable, Logging} /** - * Used by applications (and the Kernel) to publish consumer actors and active objects via + * Used by applications (and the Kernel) to publish consumer actors and typed actors via * Camel endpoints and to manage the life cycle of a a global CamelContext which can be * accessed via se.scalablesolutions.akka.camel.CamelContextManager.context. * @@ -33,8 +33,8 @@ trait CamelService extends Bootable with Logging { * Starts the CamelService. Any started actor that is a consumer actor will be (asynchronously) * published as Camel endpoint. Consumer actors that are started after this method returned will * be published as well. Actor publishing is done asynchronously. A started (loaded) CamelService - * also publishes @consume annotated methods of active objects that have been created - * with ActiveObject.newInstance(..) (and ActiveObject.newInstance(..) + * also publishes @consume annotated methods of typed actors that have been created + * with TypedActor.newInstance(..) (and TypedActor.newInstance(..) * on a remote node). */ abstract override def onLoad = { @@ -44,7 +44,7 @@ trait CamelService extends Bootable with Logging { if (!initialized) init if (!started) start - // start actor that exposes consumer actors and active objects via Camel endpoints + // start actor that exposes consumer actors and typed actors via Camel endpoints consumerPublisher.start // init publishRequestor so that buffered and future events are delivered to consumerPublisher diff --git a/akka-camel/src/main/scala/ConsumerPublisher.scala b/akka-camel/src/main/scala/ConsumerPublisher.scala index e50c625639..6ca863a561 100644 --- a/akka-camel/src/main/scala/ConsumerPublisher.scala +++ b/akka-camel/src/main/scala/ConsumerPublisher.scala @@ -13,7 +13,7 @@ import org.apache.camel.builder.RouteBuilder import se.scalablesolutions.akka.actor._ import se.scalablesolutions.akka.actor.annotation.consume -import se.scalablesolutions.akka.camel.component.ActiveObjectComponent +import se.scalablesolutions.akka.camel.component.TypedActorComponent import se.scalablesolutions.akka.util.Logging /** @@ -37,7 +37,7 @@ private[camel] object ConsumerPublisher extends Logging { } /** - * Creates a route to an active object method. + * Creates a route to an typed actor method. */ def handleConsumerMethodRegistered(event: ConsumerMethodRegistered) { val targetMethod = event.method.getName @@ -62,7 +62,7 @@ private[camel] object ConsumerPublisher extends Logging { } /** - * Actor that publishes consumer actors and active object methods at Camel endpoints. + * Actor that publishes consumer actors and typed actor methods at Camel endpoints. * The Camel context used for publishing is CamelContextManager.context. This actor * accepts messages of type * se.scalablesolutions.akka.camel.ConsumerRegistered, @@ -111,10 +111,10 @@ private[camel] case class SetExpectedRegistrationCount(num: Int) private[camel] case class SetExpectedUnregistrationCount(num: Int) /** - * Defines an abstract route to a target which is either an actor or an active object method.. + * Defines an abstract route to a target which is either an actor or an typed actor method.. * - * @param endpointUri endpoint URI of the consumer actor or active object method. - * @param id actor identifier or active object identifier (registry key). + * @param endpointUri endpoint URI of the consumer actor or typed actor method. + * @param id actor identifier or typed actor identifier (registry key). * * @author Martin Krasser */ @@ -149,20 +149,20 @@ private[camel] class ConsumerActorRoute(endpointUri: String, uuid: String, block } /** - * Defines the route to an active object method.. + * Defines the route to an typed actor method.. * * @param endpointUri endpoint URI of the consumer actor method - * @param id active object identifier + * @param id typed actor identifier * @param method name of the method to invoke. * * @author Martin Krasser */ private[camel] class ConsumerMethodRoute(val endpointUri: String, id: String, method: String) extends ConsumerRoute(endpointUri, id) { - protected override def targetUri = "%s:%s?method=%s" format (ActiveObjectComponent.InternalSchema, id, method) + protected override def targetUri = "%s:%s?method=%s" format (TypedActorComponent.InternalSchema, id, method) } /** - * A registration listener that triggers publication of consumer actors and active object + * A registration listener that triggers publication of consumer actors and typed actor * methods as well as un-publication of consumer actors. This actor needs to be initialized * with a PublishRequestorInit command message for obtaining a reference to * a publisher actor. Before initialization it buffers all outbound messages @@ -209,7 +209,7 @@ private[camel] class PublishRequestor extends Actor { /** * Command message to initialize a PublishRequestor to use consumerPublisher - * for publishing actors or active object methods. + * for publishing actors or typed actor methods. */ private[camel] case class PublishRequestorInit(consumerPublisher: ActorRef) @@ -244,13 +244,13 @@ private[camel] case class ConsumerRegistered(actorRef: ActorRef, uri: String, uu private[camel] case class ConsumerUnregistered(actorRef: ActorRef, uri: String, uuid: String) extends ConsumerEvent /** - * Event indicating that an active object proxy has been created for a POJO. For each + * Event indicating that an typed actor proxy has been created for a POJO. For each * @consume annotated POJO method a separate instance of this class is * created. * - * @param activeObject active object (proxy). + * @param activeObject typed actor (proxy). * @param init - * @param uri endpoint URI of the active object method + * @param uri endpoint URI of the typed actor method * @param method method to be published. * * @author Martin Krasser @@ -258,13 +258,13 @@ private[camel] case class ConsumerUnregistered(actorRef: ActorRef, uri: String, private[camel] case class ConsumerMethodRegistered(activeObject: AnyRef, init: AspectInit, uri: String, method: Method) extends ConsumerEvent /** - * Event indicating that an active object has been stopped. For each + * Event indicating that an typed actor has been stopped. For each * @consume annotated POJO method a separate instance of this class is * created. * - * @param activeObject active object (proxy). + * @param activeObject typed actor (proxy). * @param init - * @param uri endpoint URI of the active object method + * @param uri endpoint URI of the typed actor method * @param method method to be un-published. * * @author Martin Krasser @@ -308,14 +308,14 @@ private[camel] object ConsumerMethod { /** * Applies a function f to each consumer method of activeObject and * returns the function results as a list. A consumer method is one that is annotated with - * @consume. If activeObject is a proxy for a remote active object + * @consume. If activeObject is a proxy for a remote typed actor * f is never called and Nil is returned. */ def forConsumer[T](activeObject: AnyRef, init: AspectInit)(f: Method => T): List[T] = { // TODO: support consumer annotation inheritance // - visit overridden methods in superclasses // - visit implemented method declarations in interfaces - if (init.remoteAddress.isDefined) Nil // let remote node publish active object methods on endpoints + if (init.remoteAddress.isDefined) Nil // let remote node publish typed actor methods on endpoints else for (m <- activeObject.getClass.getMethods.toList; if (m.isAnnotationPresent(classOf[consume]))) yield f(m) } @@ -326,8 +326,8 @@ private[camel] object ConsumerMethod { */ private[camel] object ConsumerMethodRegistered { /** - * Creates a list of ConsumerMethodRegistered event messages for an active object or an empty - * list if the active object is a proxy for an remote active object or the active object doesn't + * Creates a list of ConsumerMethodRegistered event messages for an typed actor or an empty + * list if the typed actor is a proxy for an remote typed actor or the typed actor doesn't * have any @consume annotated methods. */ def forConsumer(activeObject: AnyRef, init: AspectInit): List[ConsumerMethodRegistered] = { @@ -342,8 +342,8 @@ private[camel] object ConsumerMethodRegistered { */ private[camel] object ConsumerMethodUnregistered { /** - * Creates a list of ConsumerMethodUnregistered event messages for an active object or an empty - * list if the active object is a proxy for an remote active object or the active object doesn't + * Creates a list of ConsumerMethodUnregistered event messages for an typed actor or an empty + * list if the typed actor is a proxy for an remote typed actor or the typed actor doesn't * have any @consume annotated methods. */ def forConsumer(activeObject: AnyRef, init: AspectInit): List[ConsumerMethodUnregistered] = { diff --git a/akka-camel/src/main/scala/component/ActorComponent.scala b/akka-camel/src/main/scala/component/ActorComponent.scala index 01e96b6e20..6baeaf8b3e 100644 --- a/akka-camel/src/main/scala/component/ActorComponent.scala +++ b/akka-camel/src/main/scala/component/ActorComponent.scala @@ -132,10 +132,8 @@ class ActorProducer(val ep: ActorEndpoint) extends DefaultProducer(ep) with Asyn result match { case Some(msg: Failure) => exchange.fromFailureMessage(msg) case Some(msg) => exchange.fromResponseMessage(Message.canonicalize(msg)) - case None => { - throw new TimeoutException("timeout (%d ms) while waiting response from %s" - format (actor.timeout, ep.getEndpointUri)) - } + case None => throw new TimeoutException("timeout (%d ms) while waiting response from %s" + format (actor.timeout, ep.getEndpointUri)) } } diff --git a/akka-camel/src/main/scala/component/ActiveObjectComponent.scala b/akka-camel/src/main/scala/component/TypedActorComponent.scala similarity index 71% rename from akka-camel/src/main/scala/component/ActiveObjectComponent.scala rename to akka-camel/src/main/scala/component/TypedActorComponent.scala index 05fa026e04..aff6326beb 100644 --- a/akka-camel/src/main/scala/component/ActiveObjectComponent.scala +++ b/akka-camel/src/main/scala/component/TypedActorComponent.scala @@ -12,31 +12,31 @@ import org.apache.camel.component.bean._ /** * @author Martin Krasser */ -object ActiveObjectComponent { +object TypedActorComponent { /** - * Default schema name for active object endpoint URIs. + * Default schema name for typed actor endpoint URIs. */ val InternalSchema = "active-object-internal" } /** - * Camel component for exchanging messages with active objects. This component - * tries to obtain the active object from the activeObjectRegistry + * Camel component for exchanging messages with typed actors. This component + * tries to obtain the typed actor from the activeObjectRegistry * first. If it's not there it tries to obtain it from the CamelContext's registry. * * @see org.apache.camel.component.bean.BeanComponent * * @author Martin Krasser */ -class ActiveObjectComponent extends BeanComponent { +class TypedActorComponent extends BeanComponent { val activeObjectRegistry = new ConcurrentHashMap[String, AnyRef] /** * Creates a {@link org.apache.camel.component.bean.BeanEndpoint} with a custom * bean holder that uses activeObjectRegistry for getting access to - * active objects (beans). + * typed actors (beans). * - * @see se.scalablesolutions.akka.camel.component.ActiveObjectHolder + * @see se.scalablesolutions.akka.camel.component.TypedActorHolder */ override def createEndpoint(uri: String, remaining: String, parameters: Map[String, AnyRef]) = { val endpoint = new BeanEndpoint(uri, this) @@ -47,26 +47,26 @@ class ActiveObjectComponent extends BeanComponent { } private def createBeanHolder(beanName: String) = - new ActiveObjectHolder(activeObjectRegistry, getCamelContext, beanName).createCacheHolder + new TypedActorHolder(activeObjectRegistry, getCamelContext, beanName).createCacheHolder } /** * {@link org.apache.camel.component.bean.BeanHolder} implementation that uses a custom - * registry for getting access to active objects. + * registry for getting access to typed actors. * * @author Martin Krasser */ -class ActiveObjectHolder(activeObjectRegistry: Map[String, AnyRef], context: CamelContext, name: String) +class TypedActorHolder(activeObjectRegistry: Map[String, AnyRef], context: CamelContext, name: String) extends RegistryBean(context, name) { /** - * Returns an {@link se.scalablesolutions.akka.camel.component.ActiveObjectInfo} instance. + * Returns an {@link se.scalablesolutions.akka.camel.component.TypedActorInfo} instance. */ override def getBeanInfo: BeanInfo = - new ActiveObjectInfo(getContext, getBean.getClass, getParameterMappingStrategy) + new TypedActorInfo(getContext, getBean.getClass, getParameterMappingStrategy) /** - * Obtains an active object from activeObjectRegistry. + * Obtains an typed actor from activeObjectRegistry. */ override def getBean: AnyRef = { val bean = activeObjectRegistry.get(getName) @@ -75,11 +75,11 @@ class ActiveObjectHolder(activeObjectRegistry: Map[String, AnyRef], context: Cam } /** - * Provides active object meta information. + * Provides typed actor meta information. * * @author Martin Krasser */ -class ActiveObjectInfo(context: CamelContext, clazz: Class[_], strategy: ParameterMappingStrategy) +class TypedActorInfo(context: CamelContext, clazz: Class[_], strategy: ParameterMappingStrategy) extends BeanInfo(context, clazz, strategy) { /** diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoBase.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoBase.java index 05bf1625bb..7a9b5c95cc 100644 --- a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoBase.java +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoBase.java @@ -4,11 +4,12 @@ import org.apache.camel.Body; import org.apache.camel.Header; import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.*; /** * @author Martin Krasser */ -public class PojoBase { +public class PojoBase extends TypedActor implements PojoBaseIntf { public String m1(String b, String h) { return "m1base: " + b + " " + h; diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoBaseIntf.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoBaseIntf.java new file mode 100644 index 0000000000..2ca8ef4360 --- /dev/null +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoBaseIntf.java @@ -0,0 +1,21 @@ +package se.scalablesolutions.akka.camel; + +import org.apache.camel.Body; +import org.apache.camel.Header; + +import se.scalablesolutions.akka.actor.annotation.consume; + +/** + * @author Martin Krasser + */ +public interface PojoBaseIntf { + + public String m1(String b, String h); + @consume("direct:m2base") + public String m2(@Body String b, @Header("test") String h); + @consume("direct:m3base") + public String m3(@Body String b, @Header("test") String h); + @consume("direct:m4base") + public String m4(@Body String b, @Header("test") String h); + public void m5(@Body String b, @Header("test") String h); +} diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoImpl.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoImpl.java index b48202d4dc..8866acf573 100644 --- a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoImpl.java +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoImpl.java @@ -4,11 +4,12 @@ import org.apache.camel.Body; import org.apache.camel.Header; import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.*; /** * @author Martin Krasser */ -public class PojoImpl implements PojoIntf { +public class PojoImpl extends TypedActor implements PojoIntf { public String m1(String b, String h) { return "m1impl: " + b + " " + h; @@ -18,6 +19,4 @@ public class PojoImpl implements PojoIntf { public String m2(@Body String b, @Header("test") String h) { return "m2impl: " + b + " " + h; } - - } diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/Pojo.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoNonConsumer.java similarity index 57% rename from akka-camel/src/test/java/se/scalablesolutions/akka/camel/Pojo.java rename to akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoNonConsumer.java index d1848c49ee..fc6ea834fd 100644 --- a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/Pojo.java +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoNonConsumer.java @@ -1,11 +1,11 @@ package se.scalablesolutions.akka.camel; -import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.*; /** * @author Martin Krasser */ -public class Pojo { +public class PojoNonConsumer extends TypedActor implements PojoNonConsumerIntf { public String foo(String s) { return String.format("foo: %s", s); diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoNonConsumerIntf.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoNonConsumerIntf.java new file mode 100644 index 0000000000..aec8caaf19 --- /dev/null +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoNonConsumerIntf.java @@ -0,0 +1,9 @@ +package se.scalablesolutions.akka.camel; + +/** + * @author Martin Krasser + */ +public interface PojoNonConsumerIntf { + + public String foo(String s); +} \ No newline at end of file diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoRemote.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoRemote.java index 57b0999b8f..61ea4d7a17 100644 --- a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoRemote.java +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoRemote.java @@ -1,15 +1,16 @@ package se.scalablesolutions.akka.camel; import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.*; /** * @author Martin Krasser */ -public class PojoRemote { +public class PojoRemote extends TypedActor implements PojoRemoteIntf { @consume("direct:remote-active-object") public String foo(String s) { - return String.format("remote active object: %s", s); + return String.format("remote typed actor: %s", s); } } diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoRemoteIntf.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoRemoteIntf.java new file mode 100644 index 0000000000..639a440598 --- /dev/null +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoRemoteIntf.java @@ -0,0 +1,12 @@ +package se.scalablesolutions.akka.camel; + +import se.scalablesolutions.akka.actor.annotation.consume; + +/** + * @author Martin Krasser + */ +public interface PojoRemoteIntf { + + @consume("direct:remote-active-object") + public String foo(String s); +} diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSingle.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSingle.java index 7d577535b2..d4cbe1aabe 100644 --- a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSingle.java +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSingle.java @@ -1,11 +1,12 @@ package se.scalablesolutions.akka.camel; import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.*; /** * @author Martin Krasser */ -public class PojoSingle { +public class PojoSingle extends TypedActor implements PojoSingleIntf { @consume("direct:foo") public void foo(String b) { diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSingleIntf.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSingleIntf.java new file mode 100644 index 0000000000..22a25325a3 --- /dev/null +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSingleIntf.java @@ -0,0 +1,12 @@ +package se.scalablesolutions.akka.camel; + +import se.scalablesolutions.akka.actor.annotation.consume; + +/** + * @author Martin Krasser + */ +public interface PojoSingleIntf { + + @consume("direct:foo") + public void foo(String b); +} diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSub.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSub.java index be5b453698..24caf37348 100644 --- a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSub.java +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSub.java @@ -4,8 +4,9 @@ import org.apache.camel.Body; import org.apache.camel.Header; import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.*; -public class PojoSub extends PojoBase { +public class PojoSub extends PojoBase implements PojoSubIntf { @Override @consume("direct:m1sub") diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSubIntf.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSubIntf.java new file mode 100644 index 0000000000..08a153b124 --- /dev/null +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/PojoSubIntf.java @@ -0,0 +1,18 @@ +package se.scalablesolutions.akka.camel; + +import org.apache.camel.Body; +import org.apache.camel.Header; + +import se.scalablesolutions.akka.actor.annotation.consume; + +public interface PojoSubIntf extends PojoBaseIntf { + @consume("direct:m1sub") + public String m1(@Body String b, @Header("test") String h); + + @Override + public String m2(String b, String h); + + @Override + @consume("direct:m3sub") + public String m3(@Body String b, @Header("test") String h); +} diff --git a/akka-camel/src/test/scala/CamelServiceFeatureTest.scala b/akka-camel/src/test/scala/CamelServiceFeatureTest.scala index 09d386c383..1fcbcadd64 100644 --- a/akka-camel/src/test/scala/CamelServiceFeatureTest.scala +++ b/akka-camel/src/test/scala/CamelServiceFeatureTest.scala @@ -7,7 +7,7 @@ import org.apache.camel.builder.RouteBuilder import org.scalatest.{GivenWhenThen, BeforeAndAfterAll, FeatureSpec} import se.scalablesolutions.akka.actor.Actor._ -import se.scalablesolutions.akka.actor.{ActiveObject, Actor, ActorRegistry} +import se.scalablesolutions.akka.actor.{TypedActor, Actor, ActorRegistry} class CamelServiceFeatureTest extends FeatureSpec with BeforeAndAfterAll with GivenWhenThen { import CamelServiceFeatureTest._ @@ -116,13 +116,13 @@ class CamelServiceFeatureTest extends FeatureSpec with BeforeAndAfterAll with Gi } } - feature("Publish active object methods in the global CamelContext") { + feature("Publish typed actor methods in the global CamelContext") { - scenario("access active object methods via Camel direct-endpoints") { + scenario("access typed actor methods via Camel direct-endpoints") { - given("an active object registered after CamelService startup") + given("an typed actor registered after CamelService startup") var latch = service.expectEndpointActivationCount(3) - val obj = ActiveObject.newInstance(classOf[PojoBase]) + val obj = TypedActor.newInstance(classOf[PojoBaseIntf], classOf[PojoBase]) assert(latch.await(5000, TimeUnit.MILLISECONDS)) when("requests are sent to published methods") @@ -137,23 +137,23 @@ class CamelServiceFeatureTest extends FeatureSpec with BeforeAndAfterAll with Gi // cleanup to avoid conflicts with next test (i.e. avoid multiple consumers on direct-endpoints) latch = service.expectEndpointDeactivationCount(3) - ActiveObject.stop(obj) + TypedActor.stop(obj) assert(latch.await(5000, TimeUnit.MILLISECONDS)) } } - feature("Unpublish active object method from the global CamelContext") { + feature("Unpublish typed actor method from the global CamelContext") { - scenario("access to unregistered active object method via Camel direct-endpoint fails") { + scenario("access to unregistered typed actor method via Camel direct-endpoint fails") { - given("an active object registered after CamelService startup") + given("an typed actor registered after CamelService startup") var latch = service.expectEndpointActivationCount(3) - val obj = ActiveObject.newInstance(classOf[PojoBase]) + val obj = TypedActor.newInstance(classOf[PojoBaseIntf], classOf[PojoBase]) assert(latch.await(5000, TimeUnit.MILLISECONDS)) - when("the active object is stopped") + when("the typed actor is stopped") latch = service.expectEndpointDeactivationCount(3) - ActiveObject.stop(obj) + TypedActor.stop(obj) assert(latch.await(5000, TimeUnit.MILLISECONDS)) then("the associated endpoints aren't accessible any more") @@ -180,7 +180,7 @@ object CamelServiceFeatureTest { } class TestBlocker(uri: String) extends Actor with Consumer { - self.timeout = 1 + self.timeout = 1000 def endpointUri = uri override def blocking = true protected def receive = { diff --git a/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala b/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala index 7c28c7d8ee..964fe8e7bf 100644 --- a/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala +++ b/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala @@ -4,7 +4,7 @@ import java.net.InetSocketAddress import org.scalatest.junit.JUnitSuite -import se.scalablesolutions.akka.actor.{AspectInit, ActiveObject} +import se.scalablesolutions.akka.actor.{AspectInit, TypedActor} import se.scalablesolutions.akka.camel.ConsumerMethodRegistered._ import org.junit.{AfterClass, Test} @@ -12,8 +12,8 @@ class ConsumerMethodRegisteredTest extends JUnitSuite { import ConsumerMethodRegisteredTest._ val remoteAddress = new InetSocketAddress("localhost", 8888); - val remoteAspectInit = AspectInit(classOf[String], null, Some(remoteAddress), 1000) - val localAspectInit = AspectInit(classOf[String], null, None, 1000) + val remoteAspectInit = AspectInit(classOf[String], null, null, Some(remoteAddress), 1000) + val localAspectInit = AspectInit(classOf[String], null, null, None, 1000) val ascendingMethodName = (r1: ConsumerMethodRegistered, r2: ConsumerMethodRegistered) => r1.method.getName < r2.method.getName @@ -44,14 +44,14 @@ class ConsumerMethodRegisteredTest extends JUnitSuite { } object ConsumerMethodRegisteredTest { - val activePojoBase = ActiveObject.newInstance(classOf[PojoBase]) - val activePojoSub = ActiveObject.newInstance(classOf[PojoSub]) - val activePojoIntf = ActiveObject.newInstance(classOf[PojoIntf], new PojoImpl) + val activePojoBase = TypedActor.newInstance(classOf[PojoBaseIntf], classOf[PojoBase]) + val activePojoSub = TypedActor.newInstance(classOf[PojoSubIntf], classOf[PojoSub]) + val activePojoIntf = TypedActor.newInstance(classOf[PojoIntf], classOf[PojoImpl]) @AfterClass def afterClass = { - ActiveObject.stop(activePojoBase) - ActiveObject.stop(activePojoSub) - ActiveObject.stop(activePojoIntf) + TypedActor.stop(activePojoBase) + TypedActor.stop(activePojoSub) + TypedActor.stop(activePojoIntf) } } diff --git a/akka-camel/src/test/scala/PublishRequestorTest.scala b/akka-camel/src/test/scala/PublishRequestorTest.scala index 131f4fe2b5..984f856875 100644 --- a/akka-camel/src/test/scala/PublishRequestorTest.scala +++ b/akka-camel/src/test/scala/PublishRequestorTest.scala @@ -32,8 +32,8 @@ class PublishRequestorTest extends JUnitSuite { } @Test def shouldReceiveConsumerMethodRegisteredEvent = { - val obj = ActiveObject.newInstance(classOf[PojoSingle]) - val init = AspectInit(classOf[PojoSingle], null, None, 1000) + val obj = TypedActor.newInstance(classOf[PojoSingleIntf], classOf[PojoSingle]) + val init = AspectInit(classOf[PojoSingleIntf], null, null, None, 1000) val latch = (publisher !! SetExpectedTestMessageCount(1)).as[CountDownLatch].get requestor ! AspectInitRegistered(obj, init) assert(latch.await(5000, TimeUnit.MILLISECONDS)) @@ -45,8 +45,8 @@ class PublishRequestorTest extends JUnitSuite { } @Test def shouldReceiveConsumerMethodUnregisteredEvent = { - val obj = ActiveObject.newInstance(classOf[PojoSingle]) - val init = AspectInit(classOf[PojoSingle], null, None, 1000) + val obj = TypedActor.newInstance(classOf[PojoSingleIntf], classOf[PojoSingle]) + val init = AspectInit(classOf[PojoSingleIntf], null, null, None, 1000) val latch = (publisher !! SetExpectedTestMessageCount(1)).as[CountDownLatch].get requestor ! AspectInitUnregistered(obj, init) assert(latch.await(5000, TimeUnit.MILLISECONDS)) diff --git a/akka-camel/src/test/scala/RemoteConsumerTest.scala b/akka-camel/src/test/scala/RemoteConsumerTest.scala index 25c6d6b975..3f0770127f 100644 --- a/akka-camel/src/test/scala/RemoteConsumerTest.scala +++ b/akka-camel/src/test/scala/RemoteConsumerTest.scala @@ -5,7 +5,7 @@ import java.util.concurrent.{CountDownLatch, TimeUnit} import org.scalatest.{GivenWhenThen, BeforeAndAfterAll, FeatureSpec} import se.scalablesolutions.akka.actor.Actor._ -import se.scalablesolutions.akka.actor.{ActiveObject, ActorRegistry, RemoteActor} +import se.scalablesolutions.akka.actor.{TypedActor, ActorRegistry, RemoteActor} import se.scalablesolutions.akka.remote.{RemoteClient, RemoteServer} /** @@ -55,10 +55,10 @@ class RemoteConsumerTest extends FeatureSpec with BeforeAndAfterAll with GivenWh } } - feature("Client-initiated remote consumer active object") { + feature("Client-initiated remote consumer typed actor") { scenario("access published remote consumer method") { - given("a client-initiated remote consumer active object") - val consumer = ActiveObject.newRemoteInstance(classOf[PojoRemote], host, port) + given("a client-initiated remote consumer typed actor") + val consumer = TypedActor.newRemoteInstance(classOf[PojoRemoteIntf], classOf[PojoRemote], host, port) when("remote consumer publication is triggered") var latch = service.expectEndpointActivationCount(1) @@ -67,7 +67,7 @@ class RemoteConsumerTest extends FeatureSpec with BeforeAndAfterAll with GivenWh then("the published method is accessible via its endpoint URI") val response = CamelContextManager.template.requestBody("direct:remote-active-object", "test") - assert(response === "remote active object: test") + assert(response === "remote typed actor: test") } } } diff --git a/akka-camel/src/test/scala/component/ActiveObjectComponentFeatureTest.scala b/akka-camel/src/test/scala/component/TypedActorComponentFeatureTest.scala similarity index 76% rename from akka-camel/src/test/scala/component/ActiveObjectComponentFeatureTest.scala rename to akka-camel/src/test/scala/component/TypedActorComponentFeatureTest.scala index d80eedfd7a..4a2c4e8e28 100644 --- a/akka-camel/src/test/scala/component/ActiveObjectComponentFeatureTest.scala +++ b/akka-camel/src/test/scala/component/TypedActorComponentFeatureTest.scala @@ -4,7 +4,7 @@ import org.scalatest.{BeforeAndAfterEach, BeforeAndAfterAll, FeatureSpec} import org.apache.camel.builder.RouteBuilder import se.scalablesolutions.akka.actor.Actor._ -import se.scalablesolutions.akka.actor.{ActorRegistry, ActiveObject} +import se.scalablesolutions.akka.actor.{ActorRegistry, TypedActor} import se.scalablesolutions.akka.camel._ import org.apache.camel.impl.{DefaultCamelContext, SimpleRegistry} import org.apache.camel.{ResolveEndpointFailedException, ExchangePattern, Exchange, Processor} @@ -12,14 +12,14 @@ import org.apache.camel.{ResolveEndpointFailedException, ExchangePattern, Exchan /** * @author Martin Krasser */ -class ActiveObjectComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with BeforeAndAfterEach { - import ActiveObjectComponentFeatureTest._ +class TypedActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with BeforeAndAfterEach { + import TypedActorComponentFeatureTest._ import CamelContextManager.template override protected def beforeAll = { - val activePojo = ActiveObject.newInstance(classOf[Pojo]) // not a consumer - val activePojoBase = ActiveObject.newInstance(classOf[PojoBase]) - val activePojoIntf = ActiveObject.newInstance(classOf[PojoIntf], new PojoImpl) + val activePojo = TypedActor.newInstance(classOf[PojoNonConsumerIntf], classOf[PojoNonConsumer]) // not a consumer + val activePojoBase = TypedActor.newInstance(classOf[PojoBaseIntf], classOf[PojoBase]) + val activePojoIntf = TypedActor.newInstance(classOf[PojoIntf], classOf[PojoImpl]) val registry = new SimpleRegistry registry.put("pojo", activePojo) @@ -37,8 +37,8 @@ class ActiveObjectComponentFeatureTest extends FeatureSpec with BeforeAndAfterAl ActorRegistry.shutdownAll } - feature("Communicate with an active object from a Camel application using active object endpoint URIs") { - import ActiveObjectComponent.InternalSchema + feature("Communicate with an typed actor from a Camel application using typed actor endpoint URIs") { + import TypedActorComponent.InternalSchema import ExchangePattern._ scenario("in-out exchange with proxy created from interface and method returning String") { @@ -81,14 +81,14 @@ class ActiveObjectComponentFeatureTest extends FeatureSpec with BeforeAndAfterAl } } - feature("Communicate with an active object from a Camel application from a custom Camel route") { + feature("Communicate with an typed actor from a Camel application from a custom Camel route") { - scenario("in-out exchange with externally registered active object") { + scenario("in-out exchange with externally registered typed actor") { val result = template.requestBody("direct:test", "test") assert(result === "foo: test") } - scenario("in-out exchange with internally registered active object not possible") { + scenario("in-out exchange with internally registered typed actor not possible") { intercept[ResolveEndpointFailedException] { template.requestBodyAndHeader("active-object:intf?method=m2", "x", "test", "y") } @@ -96,7 +96,7 @@ class ActiveObjectComponentFeatureTest extends FeatureSpec with BeforeAndAfterAl } } -object ActiveObjectComponentFeatureTest { +object TypedActorComponentFeatureTest { class CustomRouteBuilder extends RouteBuilder { def configure = { from("direct:test").to("active-object:pojo?method=foo") diff --git a/akka-core/src/main/java/se/scalablesolutions/akka/config/ActiveObjectGuiceModule.java b/akka-core/src/main/java/se/scalablesolutions/akka/config/TypedActorGuiceModule.java similarity index 85% rename from akka-core/src/main/java/se/scalablesolutions/akka/config/ActiveObjectGuiceModule.java rename to akka-core/src/main/java/se/scalablesolutions/akka/config/TypedActorGuiceModule.java index 60dfd4cadd..0c2ed11402 100644 --- a/akka-core/src/main/java/se/scalablesolutions/akka/config/ActiveObjectGuiceModule.java +++ b/akka-core/src/main/java/se/scalablesolutions/akka/config/TypedActorGuiceModule.java @@ -13,10 +13,10 @@ import com.google.inject.Singleton; /** * @author Jonas Bonér */ -public class ActiveObjectGuiceModule extends AbstractModule { +public class TypedActorGuiceModule extends AbstractModule { private final List bindings; - public ActiveObjectGuiceModule(final List bindings) { + public TypedActorGuiceModule(final List bindings) { this.bindings = bindings; } diff --git a/akka-core/src/main/java/se/scalablesolutions/akka/remote/protocol/RemoteProtocol.java b/akka-core/src/main/java/se/scalablesolutions/akka/remote/protocol/RemoteProtocol.java index 9af73c6c77..8babc16770 100644 --- a/akka-core/src/main/java/se/scalablesolutions/akka/remote/protocol/RemoteProtocol.java +++ b/akka-core/src/main/java/se/scalablesolutions/akka/remote/protocol/RemoteProtocol.java @@ -8,6 +8,75 @@ public final class RemoteProtocol { public static void registerAllExtensions( com.google.protobuf.ExtensionRegistry registry) { } + public enum ActorType + implements com.google.protobuf.ProtocolMessageEnum { + SCALA_ACTOR(0, 1), + JAVA_ACTOR(1, 2), + TYPED_ACTOR(2, 3), + ; + + + public final int getNumber() { return value; } + + public static ActorType valueOf(int value) { + switch (value) { + case 1: return SCALA_ACTOR; + case 2: return JAVA_ACTOR; + case 3: return TYPED_ACTOR; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ActorType findValueByNumber(int number) { + return ActorType.valueOf(number) + ; } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.getDescriptor().getEnumTypes().get(0); + } + + private static final ActorType[] VALUES = { + SCALA_ACTOR, JAVA_ACTOR, TYPED_ACTOR, + }; + public static ActorType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + private final int index; + private final int value; + private ActorType(int index, int value) { + this.index = index; + this.value = value; + } + + static { + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.getDescriptor(); + } + + // @@protoc_insertion_point(enum_scope:ActorType) + } + public enum SerializationSchemeType implements com.google.protobuf.ProtocolMessageEnum { JAVA(0, 1), @@ -53,7 +122,7 @@ public final class RemoteProtocol { } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { - return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.getDescriptor().getEnumTypes().get(0); + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.getDescriptor().getEnumTypes().get(1); } private static final SerializationSchemeType[] VALUES = { @@ -120,7 +189,7 @@ public final class RemoteProtocol { } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { - return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.getDescriptor().getEnumTypes().get(1); + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.getDescriptor().getEnumTypes().get(2); } private static final LifeCycleType[] VALUES = { @@ -1870,6 +1939,825 @@ public final class RemoteProtocol { // @@protoc_insertion_point(class_scope:MessageProtocol) } + public static final class ActorInfoProtocol extends + com.google.protobuf.GeneratedMessage { + // Use ActorInfoProtocol.newBuilder() to construct. + private ActorInfoProtocol() { + initFields(); + } + private ActorInfoProtocol(boolean noInit) {} + + private static final ActorInfoProtocol defaultInstance; + public static ActorInfoProtocol getDefaultInstance() { + return defaultInstance; + } + + public ActorInfoProtocol getDefaultInstanceForType() { + return defaultInstance; + } + + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.internal_static_ActorInfoProtocol_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.internal_static_ActorInfoProtocol_fieldAccessorTable; + } + + // required string uuid = 1; + public static final int UUID_FIELD_NUMBER = 1; + private boolean hasUuid; + private java.lang.String uuid_ = ""; + public boolean hasUuid() { return hasUuid; } + public java.lang.String getUuid() { return uuid_; } + + // required string target = 2; + public static final int TARGET_FIELD_NUMBER = 2; + private boolean hasTarget; + private java.lang.String target_ = ""; + public boolean hasTarget() { return hasTarget; } + public java.lang.String getTarget() { return target_; } + + // required uint64 timeout = 3; + public static final int TIMEOUT_FIELD_NUMBER = 3; + private boolean hasTimeout; + private long timeout_ = 0L; + public boolean hasTimeout() { return hasTimeout; } + public long getTimeout() { return timeout_; } + + // required .ActorType actorType = 4; + public static final int ACTORTYPE_FIELD_NUMBER = 4; + private boolean hasActorType; + private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType actorType_; + public boolean hasActorType() { return hasActorType; } + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType getActorType() { return actorType_; } + + // optional .TypedActorInfoProtocol typedActorInfo = 5; + public static final int TYPEDACTORINFO_FIELD_NUMBER = 5; + private boolean hasTypedActorInfo; + private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol typedActorInfo_; + public boolean hasTypedActorInfo() { return hasTypedActorInfo; } + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol getTypedActorInfo() { return typedActorInfo_; } + + private void initFields() { + actorType_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType.SCALA_ACTOR; + typedActorInfo_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.getDefaultInstance(); + } + public final boolean isInitialized() { + if (!hasUuid) return false; + if (!hasTarget) return false; + if (!hasTimeout) return false; + if (!hasActorType) return false; + if (hasTypedActorInfo()) { + if (!getTypedActorInfo().isInitialized()) return false; + } + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (hasUuid()) { + output.writeString(1, getUuid()); + } + if (hasTarget()) { + output.writeString(2, getTarget()); + } + if (hasTimeout()) { + output.writeUInt64(3, getTimeout()); + } + if (hasActorType()) { + output.writeEnum(4, getActorType().getNumber()); + } + if (hasTypedActorInfo()) { + output.writeMessage(5, getTypedActorInfo()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasUuid()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(1, getUuid()); + } + if (hasTarget()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(2, getTarget()); + } + if (hasTimeout()) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(3, getTimeout()); + } + if (hasActorType()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(4, getActorType().getNumber()); + } + if (hasTypedActorInfo()) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, getTypedActorInfo()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data, extensionRegistry) + .buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data, extensionRegistry) + .buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom(java.io.InputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input, extensionRegistry)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder { + private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol result; + + // Construct using se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.newBuilder() + private Builder() {} + + private static Builder create() { + Builder builder = new Builder(); + builder.result = new se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol(); + return builder; + } + + protected se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol internalGetResult() { + return result; + } + + public Builder clear() { + if (result == null) { + throw new IllegalStateException( + "Cannot call clear() after build()."); + } + result = new se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol(); + return this; + } + + public Builder clone() { + return create().mergeFrom(result); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.getDescriptor(); + } + + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol getDefaultInstanceForType() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.getDefaultInstance(); + } + + public boolean isInitialized() { + return result.isInitialized(); + } + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol build() { + if (result != null && !isInitialized()) { + throw newUninitializedMessageException(result); + } + return buildPartial(); + } + + private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol buildParsed() + throws com.google.protobuf.InvalidProtocolBufferException { + if (!isInitialized()) { + throw newUninitializedMessageException( + result).asInvalidProtocolBufferException(); + } + return buildPartial(); + } + + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol buildPartial() { + if (result == null) { + throw new IllegalStateException( + "build() has already been called on this Builder."); + } + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol returnMe = result; + result = null; + return returnMe; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol) { + return mergeFrom((se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol other) { + if (other == se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.getDefaultInstance()) return this; + if (other.hasUuid()) { + setUuid(other.getUuid()); + } + if (other.hasTarget()) { + setTarget(other.getTarget()); + } + if (other.hasTimeout()) { + setTimeout(other.getTimeout()); + } + if (other.hasActorType()) { + setActorType(other.getActorType()); + } + if (other.hasTypedActorInfo()) { + mergeTypedActorInfo(other.getTypedActorInfo()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder( + this.getUnknownFields()); + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + this.setUnknownFields(unknownFields.build()); + return this; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + this.setUnknownFields(unknownFields.build()); + return this; + } + break; + } + case 10: { + setUuid(input.readString()); + break; + } + case 18: { + setTarget(input.readString()); + break; + } + case 24: { + setTimeout(input.readUInt64()); + break; + } + case 32: { + int rawValue = input.readEnum(); + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType value = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(4, rawValue); + } else { + setActorType(value); + } + break; + } + case 42: { + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.Builder subBuilder = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.newBuilder(); + if (hasTypedActorInfo()) { + subBuilder.mergeFrom(getTypedActorInfo()); + } + input.readMessage(subBuilder, extensionRegistry); + setTypedActorInfo(subBuilder.buildPartial()); + break; + } + } + } + } + + + // required string uuid = 1; + public boolean hasUuid() { + return result.hasUuid(); + } + public java.lang.String getUuid() { + return result.getUuid(); + } + public Builder setUuid(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasUuid = true; + result.uuid_ = value; + return this; + } + public Builder clearUuid() { + result.hasUuid = false; + result.uuid_ = getDefaultInstance().getUuid(); + return this; + } + + // required string target = 2; + public boolean hasTarget() { + return result.hasTarget(); + } + public java.lang.String getTarget() { + return result.getTarget(); + } + public Builder setTarget(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasTarget = true; + result.target_ = value; + return this; + } + public Builder clearTarget() { + result.hasTarget = false; + result.target_ = getDefaultInstance().getTarget(); + return this; + } + + // required uint64 timeout = 3; + public boolean hasTimeout() { + return result.hasTimeout(); + } + public long getTimeout() { + return result.getTimeout(); + } + public Builder setTimeout(long value) { + result.hasTimeout = true; + result.timeout_ = value; + return this; + } + public Builder clearTimeout() { + result.hasTimeout = false; + result.timeout_ = 0L; + return this; + } + + // required .ActorType actorType = 4; + public boolean hasActorType() { + return result.hasActorType(); + } + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType getActorType() { + return result.getActorType(); + } + public Builder setActorType(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasActorType = true; + result.actorType_ = value; + return this; + } + public Builder clearActorType() { + result.hasActorType = false; + result.actorType_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorType.SCALA_ACTOR; + return this; + } + + // optional .TypedActorInfoProtocol typedActorInfo = 5; + public boolean hasTypedActorInfo() { + return result.hasTypedActorInfo(); + } + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol getTypedActorInfo() { + return result.getTypedActorInfo(); + } + public Builder setTypedActorInfo(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasTypedActorInfo = true; + result.typedActorInfo_ = value; + return this; + } + public Builder setTypedActorInfo(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.Builder builderForValue) { + result.hasTypedActorInfo = true; + result.typedActorInfo_ = builderForValue.build(); + return this; + } + public Builder mergeTypedActorInfo(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol value) { + if (result.hasTypedActorInfo() && + result.typedActorInfo_ != se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.getDefaultInstance()) { + result.typedActorInfo_ = + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.newBuilder(result.typedActorInfo_).mergeFrom(value).buildPartial(); + } else { + result.typedActorInfo_ = value; + } + result.hasTypedActorInfo = true; + return this; + } + public Builder clearTypedActorInfo() { + result.hasTypedActorInfo = false; + result.typedActorInfo_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.getDefaultInstance(); + return this; + } + + // @@protoc_insertion_point(builder_scope:ActorInfoProtocol) + } + + static { + defaultInstance = new ActorInfoProtocol(true); + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.internalForceInit(); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:ActorInfoProtocol) + } + + public static final class TypedActorInfoProtocol extends + com.google.protobuf.GeneratedMessage { + // Use TypedActorInfoProtocol.newBuilder() to construct. + private TypedActorInfoProtocol() { + initFields(); + } + private TypedActorInfoProtocol(boolean noInit) {} + + private static final TypedActorInfoProtocol defaultInstance; + public static TypedActorInfoProtocol getDefaultInstance() { + return defaultInstance; + } + + public TypedActorInfoProtocol getDefaultInstanceForType() { + return defaultInstance; + } + + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.internal_static_TypedActorInfoProtocol_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.internal_static_TypedActorInfoProtocol_fieldAccessorTable; + } + + // required string interface = 1; + public static final int INTERFACE_FIELD_NUMBER = 1; + private boolean hasInterface; + private java.lang.String interface_ = ""; + public boolean hasInterface() { return hasInterface; } + public java.lang.String getInterface() { return interface_; } + + // required string method = 2; + public static final int METHOD_FIELD_NUMBER = 2; + private boolean hasMethod; + private java.lang.String method_ = ""; + public boolean hasMethod() { return hasMethod; } + public java.lang.String getMethod() { return method_; } + + private void initFields() { + } + public final boolean isInitialized() { + if (!hasInterface) return false; + if (!hasMethod) return false; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (hasInterface()) { + output.writeString(1, getInterface()); + } + if (hasMethod()) { + output.writeString(2, getMethod()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasInterface()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(1, getInterface()); + } + if (hasMethod()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(2, getMethod()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data, extensionRegistry) + .buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return newBuilder().mergeFrom(data, extensionRegistry) + .buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom(java.io.InputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Builder builder = newBuilder(); + if (builder.mergeDelimitedFrom(input, extensionRegistry)) { + return builder.buildParsed(); + } else { + return null; + } + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return newBuilder().mergeFrom(input).buildParsed(); + } + public static se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return newBuilder().mergeFrom(input, extensionRegistry) + .buildParsed(); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder { + private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol result; + + // Construct using se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.newBuilder() + private Builder() {} + + private static Builder create() { + Builder builder = new Builder(); + builder.result = new se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol(); + return builder; + } + + protected se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol internalGetResult() { + return result; + } + + public Builder clear() { + if (result == null) { + throw new IllegalStateException( + "Cannot call clear() after build()."); + } + result = new se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol(); + return this; + } + + public Builder clone() { + return create().mergeFrom(result); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.getDescriptor(); + } + + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol getDefaultInstanceForType() { + return se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.getDefaultInstance(); + } + + public boolean isInitialized() { + return result.isInitialized(); + } + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol build() { + if (result != null && !isInitialized()) { + throw newUninitializedMessageException(result); + } + return buildPartial(); + } + + private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol buildParsed() + throws com.google.protobuf.InvalidProtocolBufferException { + if (!isInitialized()) { + throw newUninitializedMessageException( + result).asInvalidProtocolBufferException(); + } + return buildPartial(); + } + + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol buildPartial() { + if (result == null) { + throw new IllegalStateException( + "build() has already been called on this Builder."); + } + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol returnMe = result; + result = null; + return returnMe; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol) { + return mergeFrom((se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol other) { + if (other == se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.getDefaultInstance()) return this; + if (other.hasInterface()) { + setInterface(other.getInterface()); + } + if (other.hasMethod()) { + setMethod(other.getMethod()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder( + this.getUnknownFields()); + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + this.setUnknownFields(unknownFields.build()); + return this; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + this.setUnknownFields(unknownFields.build()); + return this; + } + break; + } + case 10: { + setInterface(input.readString()); + break; + } + case 18: { + setMethod(input.readString()); + break; + } + } + } + } + + + // required string interface = 1; + public boolean hasInterface() { + return result.hasInterface(); + } + public java.lang.String getInterface() { + return result.getInterface(); + } + public Builder setInterface(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasInterface = true; + result.interface_ = value; + return this; + } + public Builder clearInterface() { + result.hasInterface = false; + result.interface_ = getDefaultInstance().getInterface(); + return this; + } + + // required string method = 2; + public boolean hasMethod() { + return result.hasMethod(); + } + public java.lang.String getMethod() { + return result.getMethod(); + } + public Builder setMethod(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasMethod = true; + result.method_ = value; + return this; + } + public Builder clearMethod() { + result.hasMethod = false; + result.method_ = getDefaultInstance().getMethod(); + return this; + } + + // @@protoc_insertion_point(builder_scope:TypedActorInfoProtocol) + } + + static { + defaultInstance = new TypedActorInfoProtocol(true); + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.internalForceInit(); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:TypedActorInfoProtocol) + } + public static final class RemoteRequestProtocol extends com.google.protobuf.GeneratedMessage { // Use RemoteRequestProtocol.newBuilder() to construct. @@ -1911,64 +2799,29 @@ public final class RemoteProtocol { public boolean hasMessage() { return hasMessage; } public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.MessageProtocol getMessage() { return message_; } - // optional string method = 3; - public static final int METHOD_FIELD_NUMBER = 3; - private boolean hasMethod; - private java.lang.String method_ = ""; - public boolean hasMethod() { return hasMethod; } - public java.lang.String getMethod() { return method_; } + // required .ActorInfoProtocol actorInfo = 3; + public static final int ACTORINFO_FIELD_NUMBER = 3; + private boolean hasActorInfo; + private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol actorInfo_; + public boolean hasActorInfo() { return hasActorInfo; } + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol getActorInfo() { return actorInfo_; } - // required string target = 4; - public static final int TARGET_FIELD_NUMBER = 4; - private boolean hasTarget; - private java.lang.String target_ = ""; - public boolean hasTarget() { return hasTarget; } - public java.lang.String getTarget() { return target_; } - - // required string uuid = 5; - public static final int UUID_FIELD_NUMBER = 5; - private boolean hasUuid; - private java.lang.String uuid_ = ""; - public boolean hasUuid() { return hasUuid; } - public java.lang.String getUuid() { return uuid_; } - - // required uint64 timeout = 6; - public static final int TIMEOUT_FIELD_NUMBER = 6; - private boolean hasTimeout; - private long timeout_ = 0L; - public boolean hasTimeout() { return hasTimeout; } - public long getTimeout() { return timeout_; } - - // optional string supervisorUuid = 7; - public static final int SUPERVISORUUID_FIELD_NUMBER = 7; - private boolean hasSupervisorUuid; - private java.lang.String supervisorUuid_ = ""; - public boolean hasSupervisorUuid() { return hasSupervisorUuid; } - public java.lang.String getSupervisorUuid() { return supervisorUuid_; } - - // required bool isActor = 8; - public static final int ISACTOR_FIELD_NUMBER = 8; - private boolean hasIsActor; - private boolean isActor_ = false; - public boolean hasIsActor() { return hasIsActor; } - public boolean getIsActor() { return isActor_; } - - // required bool isOneWay = 9; - public static final int ISONEWAY_FIELD_NUMBER = 9; + // required bool isOneWay = 4; + public static final int ISONEWAY_FIELD_NUMBER = 4; private boolean hasIsOneWay; private boolean isOneWay_ = false; public boolean hasIsOneWay() { return hasIsOneWay; } public boolean getIsOneWay() { return isOneWay_; } - // required bool isEscaped = 10; - public static final int ISESCAPED_FIELD_NUMBER = 10; - private boolean hasIsEscaped; - private boolean isEscaped_ = false; - public boolean hasIsEscaped() { return hasIsEscaped; } - public boolean getIsEscaped() { return isEscaped_; } + // optional string supervisorUuid = 5; + public static final int SUPERVISORUUID_FIELD_NUMBER = 5; + private boolean hasSupervisorUuid; + private java.lang.String supervisorUuid_ = ""; + public boolean hasSupervisorUuid() { return hasSupervisorUuid; } + public java.lang.String getSupervisorUuid() { return supervisorUuid_; } - // optional .RemoteActorRefProtocol sender = 11; - public static final int SENDER_FIELD_NUMBER = 11; + // optional .RemoteActorRefProtocol sender = 6; + public static final int SENDER_FIELD_NUMBER = 6; private boolean hasSender; private se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteActorRefProtocol sender_; public boolean hasSender() { return hasSender; } @@ -1976,18 +2829,16 @@ public final class RemoteProtocol { private void initFields() { message_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.MessageProtocol.getDefaultInstance(); + actorInfo_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.getDefaultInstance(); sender_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteActorRefProtocol.getDefaultInstance(); } public final boolean isInitialized() { if (!hasId) return false; if (!hasMessage) return false; - if (!hasTarget) return false; - if (!hasUuid) return false; - if (!hasTimeout) return false; - if (!hasIsActor) return false; + if (!hasActorInfo) return false; if (!hasIsOneWay) return false; - if (!hasIsEscaped) return false; if (!getMessage().isInitialized()) return false; + if (!getActorInfo().isInitialized()) return false; if (hasSender()) { if (!getSender().isInitialized()) return false; } @@ -2003,32 +2854,17 @@ public final class RemoteProtocol { if (hasMessage()) { output.writeMessage(2, getMessage()); } - if (hasMethod()) { - output.writeString(3, getMethod()); - } - if (hasTarget()) { - output.writeString(4, getTarget()); - } - if (hasUuid()) { - output.writeString(5, getUuid()); - } - if (hasTimeout()) { - output.writeUInt64(6, getTimeout()); - } - if (hasSupervisorUuid()) { - output.writeString(7, getSupervisorUuid()); - } - if (hasIsActor()) { - output.writeBool(8, getIsActor()); + if (hasActorInfo()) { + output.writeMessage(3, getActorInfo()); } if (hasIsOneWay()) { - output.writeBool(9, getIsOneWay()); + output.writeBool(4, getIsOneWay()); } - if (hasIsEscaped()) { - output.writeBool(10, getIsEscaped()); + if (hasSupervisorUuid()) { + output.writeString(5, getSupervisorUuid()); } if (hasSender()) { - output.writeMessage(11, getSender()); + output.writeMessage(6, getSender()); } getUnknownFields().writeTo(output); } @@ -2047,41 +2883,21 @@ public final class RemoteProtocol { size += com.google.protobuf.CodedOutputStream .computeMessageSize(2, getMessage()); } - if (hasMethod()) { + if (hasActorInfo()) { size += com.google.protobuf.CodedOutputStream - .computeStringSize(3, getMethod()); - } - if (hasTarget()) { - size += com.google.protobuf.CodedOutputStream - .computeStringSize(4, getTarget()); - } - if (hasUuid()) { - size += com.google.protobuf.CodedOutputStream - .computeStringSize(5, getUuid()); - } - if (hasTimeout()) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(6, getTimeout()); - } - if (hasSupervisorUuid()) { - size += com.google.protobuf.CodedOutputStream - .computeStringSize(7, getSupervisorUuid()); - } - if (hasIsActor()) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(8, getIsActor()); + .computeMessageSize(3, getActorInfo()); } if (hasIsOneWay()) { size += com.google.protobuf.CodedOutputStream - .computeBoolSize(9, getIsOneWay()); + .computeBoolSize(4, getIsOneWay()); } - if (hasIsEscaped()) { + if (hasSupervisorUuid()) { size += com.google.protobuf.CodedOutputStream - .computeBoolSize(10, getIsEscaped()); + .computeStringSize(5, getSupervisorUuid()); } if (hasSender()) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(11, getSender()); + .computeMessageSize(6, getSender()); } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; @@ -2247,29 +3063,14 @@ public final class RemoteProtocol { if (other.hasMessage()) { mergeMessage(other.getMessage()); } - if (other.hasMethod()) { - setMethod(other.getMethod()); - } - if (other.hasTarget()) { - setTarget(other.getTarget()); - } - if (other.hasUuid()) { - setUuid(other.getUuid()); - } - if (other.hasTimeout()) { - setTimeout(other.getTimeout()); - } - if (other.hasSupervisorUuid()) { - setSupervisorUuid(other.getSupervisorUuid()); - } - if (other.hasIsActor()) { - setIsActor(other.getIsActor()); + if (other.hasActorInfo()) { + mergeActorInfo(other.getActorInfo()); } if (other.hasIsOneWay()) { setIsOneWay(other.getIsOneWay()); } - if (other.hasIsEscaped()) { - setIsEscaped(other.getIsEscaped()); + if (other.hasSupervisorUuid()) { + setSupervisorUuid(other.getSupervisorUuid()); } if (other.hasSender()) { mergeSender(other.getSender()); @@ -2313,38 +3114,23 @@ public final class RemoteProtocol { break; } case 26: { - setMethod(input.readString()); + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.Builder subBuilder = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.newBuilder(); + if (hasActorInfo()) { + subBuilder.mergeFrom(getActorInfo()); + } + input.readMessage(subBuilder, extensionRegistry); + setActorInfo(subBuilder.buildPartial()); break; } - case 34: { - setTarget(input.readString()); - break; - } - case 42: { - setUuid(input.readString()); - break; - } - case 48: { - setTimeout(input.readUInt64()); - break; - } - case 58: { - setSupervisorUuid(input.readString()); - break; - } - case 64: { - setIsActor(input.readBool()); - break; - } - case 72: { + case 32: { setIsOneWay(input.readBool()); break; } - case 80: { - setIsEscaped(input.readBool()); + case 42: { + setSupervisorUuid(input.readString()); break; } - case 90: { + case 50: { se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteActorRefProtocol.Builder subBuilder = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteActorRefProtocol.newBuilder(); if (hasSender()) { subBuilder.mergeFrom(getSender()); @@ -2413,88 +3199,62 @@ public final class RemoteProtocol { return this; } - // optional string method = 3; - public boolean hasMethod() { - return result.hasMethod(); + // required .ActorInfoProtocol actorInfo = 3; + public boolean hasActorInfo() { + return result.hasActorInfo(); } - public java.lang.String getMethod() { - return result.getMethod(); + public se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol getActorInfo() { + return result.getActorInfo(); } - public Builder setMethod(java.lang.String value) { + public Builder setActorInfo(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol value) { if (value == null) { - throw new NullPointerException(); - } - result.hasMethod = true; - result.method_ = value; + throw new NullPointerException(); + } + result.hasActorInfo = true; + result.actorInfo_ = value; return this; } - public Builder clearMethod() { - result.hasMethod = false; - result.method_ = getDefaultInstance().getMethod(); + public Builder setActorInfo(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.Builder builderForValue) { + result.hasActorInfo = true; + result.actorInfo_ = builderForValue.build(); + return this; + } + public Builder mergeActorInfo(se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol value) { + if (result.hasActorInfo() && + result.actorInfo_ != se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.getDefaultInstance()) { + result.actorInfo_ = + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.newBuilder(result.actorInfo_).mergeFrom(value).buildPartial(); + } else { + result.actorInfo_ = value; + } + result.hasActorInfo = true; + return this; + } + public Builder clearActorInfo() { + result.hasActorInfo = false; + result.actorInfo_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.getDefaultInstance(); return this; } - // required string target = 4; - public boolean hasTarget() { - return result.hasTarget(); + // required bool isOneWay = 4; + public boolean hasIsOneWay() { + return result.hasIsOneWay(); } - public java.lang.String getTarget() { - return result.getTarget(); + public boolean getIsOneWay() { + return result.getIsOneWay(); } - public Builder setTarget(java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - result.hasTarget = true; - result.target_ = value; + public Builder setIsOneWay(boolean value) { + result.hasIsOneWay = true; + result.isOneWay_ = value; return this; } - public Builder clearTarget() { - result.hasTarget = false; - result.target_ = getDefaultInstance().getTarget(); + public Builder clearIsOneWay() { + result.hasIsOneWay = false; + result.isOneWay_ = false; return this; } - // required string uuid = 5; - public boolean hasUuid() { - return result.hasUuid(); - } - public java.lang.String getUuid() { - return result.getUuid(); - } - public Builder setUuid(java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - result.hasUuid = true; - result.uuid_ = value; - return this; - } - public Builder clearUuid() { - result.hasUuid = false; - result.uuid_ = getDefaultInstance().getUuid(); - return this; - } - - // required uint64 timeout = 6; - public boolean hasTimeout() { - return result.hasTimeout(); - } - public long getTimeout() { - return result.getTimeout(); - } - public Builder setTimeout(long value) { - result.hasTimeout = true; - result.timeout_ = value; - return this; - } - public Builder clearTimeout() { - result.hasTimeout = false; - result.timeout_ = 0L; - return this; - } - - // optional string supervisorUuid = 7; + // optional string supervisorUuid = 5; public boolean hasSupervisorUuid() { return result.hasSupervisorUuid(); } @@ -2515,61 +3275,7 @@ public final class RemoteProtocol { return this; } - // required bool isActor = 8; - public boolean hasIsActor() { - return result.hasIsActor(); - } - public boolean getIsActor() { - return result.getIsActor(); - } - public Builder setIsActor(boolean value) { - result.hasIsActor = true; - result.isActor_ = value; - return this; - } - public Builder clearIsActor() { - result.hasIsActor = false; - result.isActor_ = false; - return this; - } - - // required bool isOneWay = 9; - public boolean hasIsOneWay() { - return result.hasIsOneWay(); - } - public boolean getIsOneWay() { - return result.getIsOneWay(); - } - public Builder setIsOneWay(boolean value) { - result.hasIsOneWay = true; - result.isOneWay_ = value; - return this; - } - public Builder clearIsOneWay() { - result.hasIsOneWay = false; - result.isOneWay_ = false; - return this; - } - - // required bool isEscaped = 10; - public boolean hasIsEscaped() { - return result.hasIsEscaped(); - } - public boolean getIsEscaped() { - return result.getIsEscaped(); - } - public Builder setIsEscaped(boolean value) { - result.hasIsEscaped = true; - result.isEscaped_ = value; - return this; - } - public Builder clearIsEscaped() { - result.hasIsEscaped = false; - result.isEscaped_ = false; - return this; - } - - // optional .RemoteActorRefProtocol sender = 11; + // optional .RemoteActorRefProtocol sender = 6; public boolean hasSender() { return result.hasSender(); } @@ -3207,6 +3913,20 @@ public final class RemoteProtocol { public boolean hasPostRestart() { return hasPostRestart; } public java.lang.String getPostRestart() { return postRestart_; } + // optional string init = 4; + public static final int INIT_FIELD_NUMBER = 4; + private boolean hasInit; + private java.lang.String init_ = ""; + public boolean hasInit() { return hasInit; } + public java.lang.String getInit() { return init_; } + + // optional string shutdown = 5; + public static final int SHUTDOWN_FIELD_NUMBER = 5; + private boolean hasShutdown; + private java.lang.String shutdown_ = ""; + public boolean hasShutdown() { return hasShutdown; } + public java.lang.String getShutdown() { return shutdown_; } + private void initFields() { lifeCycle_ = se.scalablesolutions.akka.remote.protocol.RemoteProtocol.LifeCycleType.PERMANENT; } @@ -3227,6 +3947,12 @@ public final class RemoteProtocol { if (hasPostRestart()) { output.writeString(3, getPostRestart()); } + if (hasInit()) { + output.writeString(4, getInit()); + } + if (hasShutdown()) { + output.writeString(5, getShutdown()); + } getUnknownFields().writeTo(output); } @@ -3248,6 +3974,14 @@ public final class RemoteProtocol { size += com.google.protobuf.CodedOutputStream .computeStringSize(3, getPostRestart()); } + if (hasInit()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(4, getInit()); + } + if (hasShutdown()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(5, getShutdown()); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -3415,6 +4149,12 @@ public final class RemoteProtocol { if (other.hasPostRestart()) { setPostRestart(other.getPostRestart()); } + if (other.hasInit()) { + setInit(other.getInit()); + } + if (other.hasShutdown()) { + setShutdown(other.getShutdown()); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -3458,6 +4198,14 @@ public final class RemoteProtocol { setPostRestart(input.readString()); break; } + case 34: { + setInit(input.readString()); + break; + } + case 42: { + setShutdown(input.readString()); + break; + } } } } @@ -3526,6 +4274,48 @@ public final class RemoteProtocol { return this; } + // optional string init = 4; + public boolean hasInit() { + return result.hasInit(); + } + public java.lang.String getInit() { + return result.getInit(); + } + public Builder setInit(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasInit = true; + result.init_ = value; + return this; + } + public Builder clearInit() { + result.hasInit = false; + result.init_ = getDefaultInstance().getInit(); + return this; + } + + // optional string shutdown = 5; + public boolean hasShutdown() { + return result.hasShutdown(); + } + public java.lang.String getShutdown() { + return result.getShutdown(); + } + public Builder setShutdown(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasShutdown = true; + result.shutdown_ = value; + return this; + } + public Builder clearShutdown() { + result.hasShutdown = false; + result.shutdown_ = getDefaultInstance().getShutdown(); + return this; + } + // @@protoc_insertion_point(builder_scope:LifeCycleProtocol) } @@ -4212,6 +5002,16 @@ public final class RemoteProtocol { private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_MessageProtocol_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_ActorInfoProtocol_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_ActorInfoProtocol_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_TypedActorInfoProtocol_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_TypedActorInfoProtocol_fieldAccessorTable; private static com.google.protobuf.Descriptors.Descriptor internal_static_RemoteRequestProtocol_descriptor; private static @@ -4262,27 +5062,33 @@ public final class RemoteProtocol { "tProtocol\"r\n\017MessageProtocol\0225\n\023serializ" + "ationScheme\030\001 \002(\0162\030.SerializationSchemeT" + "ype\022\017\n\007message\030\002 \002(\014\022\027\n\017messageManifest\030" + - "\003 \001(\014\"\374\001\n\025RemoteRequestProtocol\022\n\n\002id\030\001 " + - "\002(\004\022!\n\007message\030\002 \002(\0132\020.MessageProtocol\022\016" + - "\n\006method\030\003 \001(\t\022\016\n\006target\030\004 \002(\t\022\014\n\004uuid\030\005" + - " \002(\t\022\017\n\007timeout\030\006 \002(\004\022\026\n\016supervisorUuid\030", - "\007 \001(\t\022\017\n\007isActor\030\010 \002(\010\022\020\n\010isOneWay\030\t \002(\010" + - "\022\021\n\tisEscaped\030\n \002(\010\022\'\n\006sender\030\013 \001(\0132\027.Re" + - "moteActorRefProtocol\"\252\001\n\023RemoteReplyProt" + - "ocol\022\n\n\002id\030\001 \002(\004\022!\n\007message\030\002 \001(\0132\020.Mess" + - "ageProtocol\022%\n\texception\030\003 \001(\0132\022.Excepti" + - "onProtocol\022\026\n\016supervisorUuid\030\004 \001(\t\022\017\n\007is" + - "Actor\030\005 \002(\010\022\024\n\014isSuccessful\030\006 \002(\010\"_\n\021Lif" + - "eCycleProtocol\022!\n\tlifeCycle\030\001 \002(\0162\016.Life" + - "CycleType\022\022\n\npreRestart\030\002 \001(\t\022\023\n\013postRes" + - "tart\030\003 \001(\t\"1\n\017AddressProtocol\022\020\n\010hostnam", - "e\030\001 \002(\t\022\014\n\004port\030\002 \002(\r\"7\n\021ExceptionProtoc" + - "ol\022\021\n\tclassname\030\001 \002(\t\022\017\n\007message\030\002 \002(\t*]" + - "\n\027SerializationSchemeType\022\010\n\004JAVA\020\001\022\013\n\007S" + - "BINARY\020\002\022\016\n\nSCALA_JSON\020\003\022\r\n\tJAVA_JSON\020\004\022" + - "\014\n\010PROTOBUF\020\005*-\n\rLifeCycleType\022\r\n\tPERMAN" + - "ENT\020\001\022\r\n\tTEMPORARY\020\002B-\n)se.scalablesolut" + - "ions.akka.remote.protocolH\001" + "\003 \001(\014\"\222\001\n\021ActorInfoProtocol\022\014\n\004uuid\030\001 \002(" + + "\t\022\016\n\006target\030\002 \002(\t\022\017\n\007timeout\030\003 \002(\004\022\035\n\tac" + + "torType\030\004 \002(\0162\n.ActorType\022/\n\016typedActorI" + + "nfo\030\005 \001(\0132\027.TypedActorInfoProtocol\";\n\026Ty", + "pedActorInfoProtocol\022\021\n\tinterface\030\001 \002(\t\022" + + "\016\n\006method\030\002 \002(\t\"\300\001\n\025RemoteRequestProtoco" + + "l\022\n\n\002id\030\001 \002(\004\022!\n\007message\030\002 \002(\0132\020.Message" + + "Protocol\022%\n\tactorInfo\030\003 \002(\0132\022.ActorInfoP" + + "rotocol\022\020\n\010isOneWay\030\004 \002(\010\022\026\n\016supervisorU" + + "uid\030\005 \001(\t\022\'\n\006sender\030\006 \001(\0132\027.RemoteActorR" + + "efProtocol\"\252\001\n\023RemoteReplyProtocol\022\n\n\002id" + + "\030\001 \002(\004\022!\n\007message\030\002 \001(\0132\020.MessageProtoco" + + "l\022%\n\texception\030\003 \001(\0132\022.ExceptionProtocol" + + "\022\026\n\016supervisorUuid\030\004 \001(\t\022\017\n\007isActor\030\005 \002(", + "\010\022\024\n\014isSuccessful\030\006 \002(\010\"\177\n\021LifeCycleProt" + + "ocol\022!\n\tlifeCycle\030\001 \002(\0162\016.LifeCycleType\022" + + "\022\n\npreRestart\030\002 \001(\t\022\023\n\013postRestart\030\003 \001(\t" + + "\022\014\n\004init\030\004 \001(\t\022\020\n\010shutdown\030\005 \001(\t\"1\n\017Addr" + + "essProtocol\022\020\n\010hostname\030\001 \002(\t\022\014\n\004port\030\002 " + + "\002(\r\"7\n\021ExceptionProtocol\022\021\n\tclassname\030\001 " + + "\002(\t\022\017\n\007message\030\002 \002(\t*=\n\tActorType\022\017\n\013SCA" + + "LA_ACTOR\020\001\022\016\n\nJAVA_ACTOR\020\002\022\017\n\013TYPED_ACTO" + + "R\020\003*]\n\027SerializationSchemeType\022\010\n\004JAVA\020\001" + + "\022\013\n\007SBINARY\020\002\022\016\n\nSCALA_JSON\020\003\022\r\n\tJAVA_JS", + "ON\020\004\022\014\n\010PROTOBUF\020\005*-\n\rLifeCycleType\022\r\n\tP" + + "ERMANENT\020\001\022\r\n\tTEMPORARY\020\002B-\n)se.scalable" + + "solutions.akka.remote.protocolH\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -4313,16 +5119,32 @@ public final class RemoteProtocol { new java.lang.String[] { "SerializationScheme", "Message", "MessageManifest", }, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.MessageProtocol.class, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.MessageProtocol.Builder.class); - internal_static_RemoteRequestProtocol_descriptor = + internal_static_ActorInfoProtocol_descriptor = getDescriptor().getMessageTypes().get(3); + internal_static_ActorInfoProtocol_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_ActorInfoProtocol_descriptor, + new java.lang.String[] { "Uuid", "Target", "Timeout", "ActorType", "TypedActorInfo", }, + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.class, + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.ActorInfoProtocol.Builder.class); + internal_static_TypedActorInfoProtocol_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_TypedActorInfoProtocol_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_TypedActorInfoProtocol_descriptor, + new java.lang.String[] { "Interface", "Method", }, + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.class, + se.scalablesolutions.akka.remote.protocol.RemoteProtocol.TypedActorInfoProtocol.Builder.class); + internal_static_RemoteRequestProtocol_descriptor = + getDescriptor().getMessageTypes().get(5); internal_static_RemoteRequestProtocol_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_RemoteRequestProtocol_descriptor, - new java.lang.String[] { "Id", "Message", "Method", "Target", "Uuid", "Timeout", "SupervisorUuid", "IsActor", "IsOneWay", "IsEscaped", "Sender", }, + new java.lang.String[] { "Id", "Message", "ActorInfo", "IsOneWay", "SupervisorUuid", "Sender", }, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteRequestProtocol.class, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteRequestProtocol.Builder.class); internal_static_RemoteReplyProtocol_descriptor = - getDescriptor().getMessageTypes().get(4); + getDescriptor().getMessageTypes().get(6); internal_static_RemoteReplyProtocol_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_RemoteReplyProtocol_descriptor, @@ -4330,15 +5152,15 @@ public final class RemoteProtocol { se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteReplyProtocol.class, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteReplyProtocol.Builder.class); internal_static_LifeCycleProtocol_descriptor = - getDescriptor().getMessageTypes().get(5); + getDescriptor().getMessageTypes().get(7); internal_static_LifeCycleProtocol_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_LifeCycleProtocol_descriptor, - new java.lang.String[] { "LifeCycle", "PreRestart", "PostRestart", }, + new java.lang.String[] { "LifeCycle", "PreRestart", "PostRestart", "Init", "Shutdown", }, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.LifeCycleProtocol.class, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.LifeCycleProtocol.Builder.class); internal_static_AddressProtocol_descriptor = - getDescriptor().getMessageTypes().get(6); + getDescriptor().getMessageTypes().get(8); internal_static_AddressProtocol_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_AddressProtocol_descriptor, @@ -4346,7 +5168,7 @@ public final class RemoteProtocol { se.scalablesolutions.akka.remote.protocol.RemoteProtocol.AddressProtocol.class, se.scalablesolutions.akka.remote.protocol.RemoteProtocol.AddressProtocol.Builder.class); internal_static_ExceptionProtocol_descriptor = - getDescriptor().getMessageTypes().get(7); + getDescriptor().getMessageTypes().get(9); internal_static_ExceptionProtocol_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_ExceptionProtocol_descriptor, diff --git a/akka-core/src/main/protocol/RemoteProtocol.proto b/akka-core/src/main/protocol/RemoteProtocol.proto index c4e5a8157e..0417251d55 100644 --- a/akka-core/src/main/protocol/RemoteProtocol.proto +++ b/akka-core/src/main/protocol/RemoteProtocol.proto @@ -52,21 +52,35 @@ message MessageProtocol { optional bytes messageManifest = 3; } +/** + * Defines the actor info. + */ +message ActorInfoProtocol { + required string uuid = 1; + required string target = 2; + required uint64 timeout = 3; + required ActorType actorType = 4; + optional TypedActorInfoProtocol typedActorInfo = 5; +} + +/** + * Defines the typed actor extra info. + */ +message TypedActorInfoProtocol { + required string interface = 1; + required string method = 2; +} + /** * Defines a remote message request. */ message RemoteRequestProtocol { required uint64 id = 1; required MessageProtocol message = 2; - optional string method = 3; - required string target = 4; - required string uuid = 5; - required uint64 timeout = 6; - optional string supervisorUuid = 7; - required bool isActor = 8; - required bool isOneWay = 9; - required bool isEscaped = 10; - optional RemoteActorRefProtocol sender = 11; + required ActorInfoProtocol actorInfo = 3; + required bool isOneWay = 4; + optional string supervisorUuid = 5; + optional RemoteActorRefProtocol sender = 6; } /** @@ -81,6 +95,15 @@ message RemoteReplyProtocol { required bool isSuccessful = 6; } +/** + * Defines the actor type. + */ +enum ActorType { + SCALA_ACTOR = 1; + JAVA_ACTOR = 2; + TYPED_ACTOR = 3; +} + /** * Defines the serialization scheme used to serialize the message and/or Actor instance. */ @@ -117,6 +140,8 @@ message LifeCycleProtocol { required LifeCycleType lifeCycle = 1; optional string preRestart = 2; optional string postRestart = 3; + optional string init = 4; + optional string shutdown = 5; } /** diff --git a/akka-core/src/main/resources/META-INF/aop.xml b/akka-core/src/main/resources/META-INF/aop.xml index 2f8d5159a8..bdc167ca54 100644 --- a/akka-core/src/main/resources/META-INF/aop.xml +++ b/akka-core/src/main/resources/META-INF/aop.xml @@ -1,7 +1,7 @@ - + diff --git a/akka-core/src/main/scala/actor/ActiveObject.scala b/akka-core/src/main/scala/actor/ActiveObject.scala deleted file mode 100644 index 83ac1fc924..0000000000 --- a/akka-core/src/main/scala/actor/ActiveObject.scala +++ /dev/null @@ -1,853 +0,0 @@ -/** - * Copyright (C) 2009-2010 Scalable Solutions AB - */ - -package se.scalablesolutions.akka.actor - -import Actor._ -import se.scalablesolutions.akka.config.FaultHandlingStrategy -import se.scalablesolutions.akka.remote.protocol.RemoteProtocol.RemoteRequestProtocol -import se.scalablesolutions.akka.remote.{MessageSerializer, RemoteClient, RemoteRequestProtocolIdFactory} -import se.scalablesolutions.akka.dispatch.{MessageDispatcher, Future, CompletableFuture} -import se.scalablesolutions.akka.config.ScalaConfig._ -import se.scalablesolutions.akka.serialization.Serializer -import se.scalablesolutions.akka.util._ - -import org.codehaus.aspectwerkz.joinpoint.{MethodRtti, JoinPoint} -import org.codehaus.aspectwerkz.proxy.Proxy -import org.codehaus.aspectwerkz.annotation.{Aspect, Around} - -import java.net.InetSocketAddress -import java.lang.reflect.{InvocationTargetException, Method} - -object Annotations { - import se.scalablesolutions.akka.actor.annotation._ - val transactionrequired = classOf[transactionrequired] - val prerestart = classOf[prerestart] - val postrestart = classOf[postrestart] - val shutdown = classOf[shutdown] - val inittransactionalstate = classOf[inittransactionalstate] -} - -/** - * Configuration factory for Active Objects. - * - * FIXDOC: document ActiveObjectConfiguration - */ -final class ActiveObjectConfiguration { - private[akka] var _timeout: Long = Actor.TIMEOUT - private[akka] var _restartCallbacks: Option[RestartCallbacks] = None - private[akka] var _shutdownCallback: Option[ShutdownCallback] = None - private[akka] var _transactionRequired = false - private[akka] var _host: Option[InetSocketAddress] = None - private[akka] var _messageDispatcher: Option[MessageDispatcher] = None - - def timeout = _timeout - def timeout(timeout: Duration) : ActiveObjectConfiguration = { - _timeout = timeout.toMillis - this - } - - def restartCallbacks(pre: String, post: String) : ActiveObjectConfiguration = { - _restartCallbacks = Some(new RestartCallbacks(pre, post)) - this - } - - def shutdownCallback(down: String) : ActiveObjectConfiguration = { - _shutdownCallback = Some(new ShutdownCallback(down)) - this - } - - def makeTransactionRequired() : ActiveObjectConfiguration = { - _transactionRequired = true; - this - } - - def makeRemote(hostname: String, port: Int) : ActiveObjectConfiguration = { - _host = Some(new InetSocketAddress(hostname, port)) - this - } - - def dispatcher(messageDispatcher: MessageDispatcher) : ActiveObjectConfiguration = { - _messageDispatcher = Some(messageDispatcher) - this - } -} - -/** - * Holds RTTI (runtime type information) for the Active Object, f.e. current 'sender' - * reference, the 'senderFuture' reference etc. - *

- * In order to make use of this context you have to create a member field in your - * Active Object that has the type 'ActiveObjectContext', then an instance will - * be injected for you to use. - *

- * This class does not contain static information but is updated by the runtime system - * at runtime. - *

- * Here is an example of usage: - *

- * class Ping {
- *   // This context will be injected, holds RTTI (runtime type information)
- *   // for the current message send
- *   private ActiveObjectContext context = null;
- *
- *   public void hit(int count) {
- *     Pong pong = (Pong) context.getSender();
- *     pong.hit(count++)
- *   }
- * }
- * 
- * - * @author Jonas Bonér - */ -final class ActiveObjectContext { - private[akka] var _sender: AnyRef = _ - private[akka] var _senderFuture: CompletableFuture[Any] = _ - - /** - * Returns the current sender Active Object reference. - * Scala style getter. - */ - def sender: AnyRef = { - if (_sender eq null) throw new IllegalActorStateException("Sender reference should not be null.") - else _sender - } - - /** - * Returns the current sender Active Object reference. - * Java style getter. - */ - def getSender: AnyRef = { - if (_sender eq null) throw new IllegalActorStateException("Sender reference should not be null.") - else _sender - } - - /** - * Returns the current sender future Active Object reference. - * Scala style getter. - */ - def senderFuture: Option[CompletableFuture[Any]] = if (_senderFuture eq null) None else Some(_senderFuture) - - /** - * Returns the current sender future Active Object reference. - * Java style getter. - * This method returns 'null' if the sender future is not available. - */ - def getSenderFuture = _senderFuture -} - -/** - * Internal helper class to help pass the contextual information between threads. - * - * @author Jonas Bonér - */ -private[akka] object ActiveObjectContext { - import scala.util.DynamicVariable - private[actor] val sender = new DynamicVariable[AnyRef](null) - private[actor] val senderFuture = new DynamicVariable[CompletableFuture[Any]](null) -} - -/** - * Factory class for creating Active Objects out of plain POJOs and/or POJOs with interfaces. - * - * @author Jonas Bonér - */ -object ActiveObject extends Logging { - import Actor.actorOf - - val AKKA_CAMEL_ROUTING_SCHEME = "akka" - private[actor] val AW_PROXY_PREFIX = "$$ProxiedByAW".intern - - def newInstance[T](target: Class[T], timeout: Long): T = - newInstance(target, actorOf(new Dispatcher(false)), None, timeout) - - def newInstance[T](target: Class[T]): T = - newInstance(target, actorOf(new Dispatcher(false)), None, Actor.TIMEOUT) - - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long): T = - newInstance(intf, target, actorOf(new Dispatcher(false)), None, timeout) - - def newInstance[T](intf: Class[T], target: AnyRef): T = - newInstance(intf, target, actorOf(new Dispatcher(false)), None, Actor.TIMEOUT) - - def newRemoteInstance[T](target: Class[T], timeout: Long, hostname: String, port: Int): T = - newInstance(target, actorOf(new Dispatcher(false)), Some(new InetSocketAddress(hostname, port)), timeout) - - def newRemoteInstance[T](target: Class[T], hostname: String, port: Int): T = - newInstance(target, actorOf(new Dispatcher(false)), Some(new InetSocketAddress(hostname, port)), Actor.TIMEOUT) - - def newInstance[T](target: Class[T], config: ActiveObjectConfiguration): T = { - val actor = actorOf(new Dispatcher(config._transactionRequired, config._restartCallbacks, config._shutdownCallback)) - if (config._messageDispatcher.isDefined) { - actor.dispatcher = config._messageDispatcher.get - } - newInstance(target, actor, config._host, config.timeout) - } - - def newInstance[T](intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration): T = { - val actor = actorOf(new Dispatcher(config._transactionRequired, config._restartCallbacks, config._shutdownCallback)) - if (config._messageDispatcher.isDefined) { - actor.dispatcher = config._messageDispatcher.get - } - newInstance(intf, target, actor, config._host, config.timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newInstance[T](target: Class[T], timeout: Long, restartCallbacks: Option[RestartCallbacks]): T = - newInstance(target, actorOf(new Dispatcher(false, restartCallbacks)), None, timeout) - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long, restartCallbacks: Option[RestartCallbacks]): T = - newInstance(intf, target, actorOf(new Dispatcher(false, restartCallbacks)), None, timeout) - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean): T = - newInstance(target, actorOf(new Dispatcher(transactionRequired, None)), None, timeout) - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean, restartCallbacks: Option[RestartCallbacks]): T = - newInstance(target, actorOf(new Dispatcher(transactionRequired, restartCallbacks)), None, timeout) - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean): T = - newInstance(intf, target, actorOf(new Dispatcher(transactionRequired, None)), None, timeout) - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean, restartCallbacks: Option[RestartCallbacks]): T = - newInstance(intf, target, actorOf(new Dispatcher(transactionRequired, restartCallbacks)), None, timeout) - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, hostname: String, port: Int): T = - newInstance(intf, target, actorOf(new Dispatcher(false, None)), Some(new InetSocketAddress(hostname, port)), timeout) - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, hostname: String, port: Int, restartCallbacks: Option[RestartCallbacks]): T = - newInstance(intf, target, actorOf(new Dispatcher(false, restartCallbacks)), Some(new InetSocketAddress(hostname, port)), timeout) - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean, hostname: String, port: Int): T = - newInstance(target, actorOf(new Dispatcher(transactionRequired, None)), Some(new InetSocketAddress(hostname, port)), timeout) - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean, hostname: String, port: Int, restartCallbacks: Option[RestartCallbacks]): T = - newInstance(target, actorOf(new Dispatcher(transactionRequired, restartCallbacks)), Some(new InetSocketAddress(hostname, port)), timeout) - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean, hostname: String, port: Int): T = - newInstance(intf, target, actorOf(new Dispatcher(transactionRequired, None)), Some(new InetSocketAddress(hostname, port)), timeout) - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean, hostname: String, port: Int, restartCallbacks: Option[RestartCallbacks]): T = - newInstance(intf, target, actorOf(new Dispatcher(transactionRequired, restartCallbacks)), Some(new InetSocketAddress(hostname, port)), timeout) - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newInstance[T](target: Class[T], timeout: Long, dispatcher: MessageDispatcher): T = { - val actor = actorOf(new Dispatcher(false, None)) - actor.dispatcher = dispatcher - newInstance(target, actor, None, timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newInstance[T](target: Class[T], timeout: Long, dispatcher: MessageDispatcher, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(false, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(target, actor, None, timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long, dispatcher: MessageDispatcher): T = { - val actor = actorOf(new Dispatcher(false, None)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, None, timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long, - dispatcher: MessageDispatcher, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(false, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, None, timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean, dispatcher: MessageDispatcher): T = { - val actor = actorOf(new Dispatcher(transactionRequired, None)) - actor.dispatcher = dispatcher - newInstance(target, actor, None, timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean, - dispatcher: MessageDispatcher, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(transactionRequired, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(target, actor, None, timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean, dispatcher: MessageDispatcher): T = { - val actor = actorOf(new Dispatcher(transactionRequired, None)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, None, timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean, - dispatcher: MessageDispatcher, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(transactionRequired, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, None, timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](target: Class[T], timeout: Long, dispatcher: MessageDispatcher, hostname: String, port: Int): T = { - val actor = actorOf(new Dispatcher(false, None)) - actor.dispatcher = dispatcher - newInstance(target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](target: Class[T], timeout: Long, dispatcher: MessageDispatcher, - hostname: String, port: Int, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(false, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, dispatcher: MessageDispatcher, hostname: String, port: Int): T = { - val actor = actorOf(new Dispatcher(false, None)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, dispatcher: MessageDispatcher, - hostname: String, port: Int, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(false, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean, - dispatcher: MessageDispatcher, hostname: String, port: Int): T = { - val actor = actorOf(new Dispatcher(transactionRequired, None)) - actor.dispatcher = dispatcher - newInstance(target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - @deprecated("use newInstance(target: Class[T], config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](target: Class[T], timeout: Long, transactionRequired: Boolean, dispatcher: MessageDispatcher, - hostname: String, port: Int, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(transactionRequired, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean, - dispatcher: MessageDispatcher, hostname: String, port: Int): T = { - val actor = actorOf(new Dispatcher(transactionRequired, None)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - @deprecated("use newInstance(intf: Class[T], target: AnyRef, config: ActiveObjectConfiguration) instead") - def newRemoteInstance[T](intf: Class[T], target: AnyRef, timeout: Long, transactionRequired: Boolean, - dispatcher: MessageDispatcher, hostname: String, port: Int, restartCallbacks: Option[RestartCallbacks]): T = { - val actor = actorOf(new Dispatcher(transactionRequired, restartCallbacks)) - actor.dispatcher = dispatcher - newInstance(intf, target, actor, Some(new InetSocketAddress(hostname, port)), timeout) - } - - private[akka] def newInstance[T](target: Class[T], actorRef: ActorRef, remoteAddress: Option[InetSocketAddress], timeout: Long): T = { - val proxy = Proxy.newInstance(target, true, false) - val context = injectActiveObjectContext(proxy) - actorRef.actor.asInstanceOf[Dispatcher].initialize(target, proxy, context) - actorRef.timeout = timeout - if (remoteAddress.isDefined) actorRef.makeRemote(remoteAddress.get) - AspectInitRegistry.register(proxy, AspectInit(target, actorRef, remoteAddress, timeout)) - actorRef.start - proxy.asInstanceOf[T] - } - - private[akka] def newInstance[T](intf: Class[T], target: AnyRef, actorRef: ActorRef, - remoteAddress: Option[InetSocketAddress], timeout: Long): T = { - val context = injectActiveObjectContext(target) - val proxy = Proxy.newInstance(Array(intf), Array(target), true, false) - actorRef.actor.asInstanceOf[Dispatcher].initialize(target.getClass, target, context) - actorRef.timeout = timeout - if (remoteAddress.isDefined) actorRef.makeRemote(remoteAddress.get) - AspectInitRegistry.register(proxy, AspectInit(intf, actorRef, remoteAddress, timeout)) - actorRef.start - proxy.asInstanceOf[T] - } - - def stop(obj: AnyRef): Unit = { - val init = AspectInitRegistry.initFor(obj) - init.actorRef.stop - } - - /** - * Get the underlying dispatcher actor for the given active object. - */ - def actorFor(obj: AnyRef): Option[ActorRef] = - ActorRegistry.actorsFor(classOf[Dispatcher]).find(a => a.actor.asInstanceOf[Dispatcher].target == Some(obj)) - - /** - * Links an other active object to this active object. - * @param supervisor the supervisor active object - * @param supervised the active object to link - */ - def link(supervisor: AnyRef, supervised: AnyRef) = { - val supervisorActor = actorFor(supervisor).getOrElse( - throw new IllegalActorStateException("Can't link when the supervisor is not an active object")) - val supervisedActor = actorFor(supervised).getOrElse( - throw new IllegalActorStateException("Can't link when the supervised is not an active object")) - supervisorActor.link(supervisedActor) - } - - /** - * Links an other active object to this active object and sets the fault handling for the supervisor. - * @param supervisor the supervisor active object - * @param supervised the active object to link - * @param handler fault handling strategy - * @param trapExceptions array of exceptions that should be handled by the supervisor - */ - def link(supervisor: AnyRef, supervised: AnyRef, handler: FaultHandlingStrategy, trapExceptions: Array[Class[_ <: Throwable]]) = { - val supervisorActor = actorFor(supervisor).getOrElse( - throw new IllegalActorStateException("Can't link when the supervisor is not an active object")) - val supervisedActor = actorFor(supervised).getOrElse( - throw new IllegalActorStateException("Can't link when the supervised is not an active object")) - supervisorActor.trapExit = trapExceptions.toList - supervisorActor.faultHandler = Some(handler) - supervisorActor.link(supervisedActor) - } - - /** - * Unlink the supervised active object from the supervisor. - * @param supervisor the supervisor active object - * @param supervised the active object to unlink - */ - def unlink(supervisor: AnyRef, supervised: AnyRef) = { - val supervisorActor = actorFor(supervisor).getOrElse( - throw new IllegalActorStateException("Can't unlink when the supervisor is not an active object")) - val supervisedActor = actorFor(supervised).getOrElse( - throw new IllegalActorStateException("Can't unlink when the supervised is not an active object")) - supervisorActor.unlink(supervisedActor) - } - - /** - * Sets the trap exit for the given supervisor active object. - * @param supervisor the supervisor active object - * @param trapExceptions array of exceptions that should be handled by the supervisor - */ - def trapExit(supervisor: AnyRef, trapExceptions: Array[Class[_ <: Throwable]]) = { - val supervisorActor = actorFor(supervisor).getOrElse( - throw new IllegalActorStateException("Can't set trap exceptions when the supervisor is not an active object")) - supervisorActor.trapExit = trapExceptions.toList - this - } - - /** - * Sets the fault handling strategy for the given supervisor active object. - * @param supervisor the supervisor active object - * @param handler fault handling strategy - */ - def faultHandler(supervisor: AnyRef, handler: FaultHandlingStrategy) = { - val supervisorActor = actorFor(supervisor).getOrElse( - throw new IllegalActorStateException("Can't set fault handler when the supervisor is not an active object")) - supervisorActor.faultHandler = Some(handler) - this - } - - private def injectActiveObjectContext(activeObject: AnyRef): Option[ActiveObjectContext] = { - def injectActiveObjectContext0(activeObject: AnyRef, clazz: Class[_]): Option[ActiveObjectContext] = { - val contextField = clazz.getDeclaredFields.toList.find(_.getType == classOf[ActiveObjectContext]) - if (contextField.isDefined) { - contextField.get.setAccessible(true) - val context = new ActiveObjectContext - contextField.get.set(activeObject, context) - Some(context) - } else { - val parent = clazz.getSuperclass - if (parent != null) injectActiveObjectContext0(activeObject, parent) - else { - log.ifTrace("Can't set 'ActiveObjectContext' for ActiveObject [" + - activeObject.getClass.getName + - "] since no field of this type could be found.") - None - } - } - } - injectActiveObjectContext0(activeObject, activeObject.getClass) - } - - private[akka] def supervise(restartStrategy: RestartStrategy, components: List[Supervise]): Supervisor = - Supervisor(SupervisorConfig(restartStrategy, components)) -} - -private[akka] object AspectInitRegistry extends ListenerManagement { - private val initializations = new java.util.concurrent.ConcurrentHashMap[AnyRef, AspectInit] - - def initFor(target: AnyRef) = { - initializations.get(target) - } - - def register(target: AnyRef, init: AspectInit) = { - val res = initializations.put(target, init) - foreachListener(_ ! AspectInitRegistered(target, init)) - res - } - - def unregister(target: AnyRef) = { - val res = initializations.remove(target) - foreachListener(_ ! AspectInitUnregistered(target, res)) - res - } -} - -private[akka] sealed trait AspectInitRegistryEvent -private[akka] case class AspectInitRegistered(proxy: AnyRef, init: AspectInit) extends AspectInitRegistryEvent -private[akka] case class AspectInitUnregistered(proxy: AnyRef, init: AspectInit) extends AspectInitRegistryEvent - -private[akka] sealed case class AspectInit( - val target: Class[_], - val actorRef: ActorRef, - val remoteAddress: Option[InetSocketAddress], - val timeout: Long) { - def this(target: Class[_], actorRef: ActorRef, timeout: Long) = this(target, actorRef, None, timeout) -} - -/** - * AspectWerkz Aspect that is turning POJOs into Active Object. - * Is deployed on a 'per-instance' basis. - * - * @author Jonas Bonér - */ -@Aspect("perInstance") -private[akka] sealed class ActiveObjectAspect { - @volatile private var isInitialized = false - @volatile private var isStopped = false - private var target: Class[_] = _ - private var actorRef: ActorRef = _ - private var remoteAddress: Option[InetSocketAddress] = _ - private var timeout: Long = _ - @volatile private var instance: AnyRef = _ - - @Around("execution(* *.*(..))") - def invoke(joinPoint: JoinPoint): AnyRef = { - if (!isInitialized) { - val init = AspectInitRegistry.initFor(joinPoint.getThis) - target = init.target - actorRef = init.actorRef - remoteAddress = init.remoteAddress - timeout = init.timeout - isInitialized = true - - } - dispatch(joinPoint) - } - - private def dispatch(joinPoint: JoinPoint) = { - if (remoteAddress.isDefined) remoteDispatch(joinPoint) - else localDispatch(joinPoint) - } - - private def localDispatch(joinPoint: JoinPoint): AnyRef = { - val rtti = joinPoint.getRtti.asInstanceOf[MethodRtti] - val isOneWay = isVoid(rtti) - val sender = ActiveObjectContext.sender.value - val senderFuture = ActiveObjectContext.senderFuture.value - - if (!actorRef.isRunning && !isStopped) { - isStopped = true - joinPoint.proceed - } else if (isOneWay) { - actorRef ! Invocation(joinPoint, true, true, sender, senderFuture) - null.asInstanceOf[AnyRef] - } else { - val result = (actorRef !! (Invocation(joinPoint, false, isOneWay, sender, senderFuture), timeout)).as[AnyRef] - if (result.isDefined) result.get - else throw new IllegalActorStateException("No result defined for invocation [" + joinPoint + "]") - } - } - - private def remoteDispatch(joinPoint: JoinPoint): AnyRef = { - val rtti = joinPoint.getRtti.asInstanceOf[MethodRtti] - val isOneWay = isVoid(rtti) - val (message: Array[AnyRef], isEscaped) = escapeArguments(rtti.getParameterValues) - val requestBuilder = RemoteRequestProtocol.newBuilder - .setId(RemoteRequestProtocolIdFactory.nextId) - .setMessage(MessageSerializer.serialize(message)) - .setMethod(rtti.getMethod.getName) - .setTarget(target.getName) - .setUuid(actorRef.uuid) - .setTimeout(timeout) - .setIsActor(false) - .setIsOneWay(isOneWay) - .setIsEscaped(false) - val id = actorRef.registerSupervisorAsRemoteActor - if (id.isDefined) requestBuilder.setSupervisorUuid(id.get) - val remoteMessage = requestBuilder.build - val future = RemoteClient.clientFor(remoteAddress.get).send(remoteMessage, None) - if (isOneWay) null // for void methods - else { - if (future.isDefined) { - future.get.await - val result = getResultOrThrowException(future.get) - if (result.isDefined) result.get - else throw new IllegalActorStateException("No result returned from call to [" + joinPoint + "]") - } else throw new IllegalActorStateException("No future returned from call to [" + joinPoint + "]") - } - } - - private def getResultOrThrowException[T](future: Future[T]): Option[T] = - if (future.exception.isDefined) { - val (_, cause) = future.exception.get - throw cause - } else future.result - - private def isVoid(rtti: MethodRtti) = rtti.getMethod.getReturnType == java.lang.Void.TYPE - - private def escapeArguments(args: Array[AnyRef]): Tuple2[Array[AnyRef], Boolean] = { - var isEscaped = false - val escapedArgs = for (arg <- args) yield { - val clazz = arg.getClass - if (clazz.getName.contains(ActiveObject.AW_PROXY_PREFIX)) { - isEscaped = true - ActiveObject.AW_PROXY_PREFIX + clazz.getSuperclass.getName - } else arg - } - (escapedArgs, isEscaped) - } -} - -/** - * Represents a snapshot of the current invocation. - * - * @author Jonas Bonér - */ -@serializable private[akka] case class Invocation( - joinPoint: JoinPoint, isOneWay: Boolean, isVoid: Boolean, sender: AnyRef, senderFuture: CompletableFuture[Any]) { - - override def toString: String = synchronized { - "Invocation [" + - "\n\t\tmethod = " + joinPoint.getRtti.asInstanceOf[MethodRtti].getMethod.getName + " @ " + joinPoint.getTarget.getClass.getName + - "\n\t\tisOneWay = " + isOneWay + - "\n\t\tisVoid = " + isVoid + - "\n\t\tsender = " + sender + - "\n\t\tsenderFuture = " + senderFuture + - "]" - } - - override def hashCode: Int = synchronized { - var result = HashCode.SEED - result = HashCode.hash(result, joinPoint) - result = HashCode.hash(result, isOneWay) - result = HashCode.hash(result, isVoid) - result = HashCode.hash(result, sender) - result = HashCode.hash(result, senderFuture) - result - } - - override def equals(that: Any): Boolean = synchronized { - that != null && - that.isInstanceOf[Invocation] && - that.asInstanceOf[Invocation].joinPoint == joinPoint && - that.asInstanceOf[Invocation].isOneWay == isOneWay && - that.asInstanceOf[Invocation].isVoid == isVoid && - that.asInstanceOf[Invocation].sender == sender && - that.asInstanceOf[Invocation].senderFuture == senderFuture - } -} - -object Dispatcher { - val ZERO_ITEM_CLASS_ARRAY = Array[Class[_]]() - val ZERO_ITEM_OBJECT_ARRAY = Array[Object]() - var crashedActorTl:ThreadLocal[Dispatcher] = new ThreadLocal(); -} - -/** - * Generic Actor managing Invocation dispatch, transaction and error management. - * - * @author Jonas Bonér - */ -private[akka] class Dispatcher(transactionalRequired: Boolean, - var restartCallbacks: Option[RestartCallbacks] = None, - var shutdownCallback: Option[ShutdownCallback] = None) extends Actor { - import Dispatcher._ - - private[actor] var target: Option[AnyRef] = None - private var zhutdown: Option[Method] = None - private var preRestart: Option[Method] = None - private var postRestart: Option[Method] = None - private var initTxState: Option[Method] = None - private var context: Option[ActiveObjectContext] = None - private var targetClass:Class[_] = _ - - def this(transactionalRequired: Boolean) = this(transactionalRequired,None) - - private[actor] def initialize(targetClass: Class[_], targetInstance: AnyRef, ctx: Option[ActiveObjectContext]) = { - - if (transactionalRequired || targetClass.isAnnotationPresent(Annotations.transactionrequired)) - self.makeTransactionRequired - self.id = targetClass.getName - this.targetClass = targetClass - target = Some(targetInstance) - context = ctx - val methods = targetInstance.getClass.getDeclaredMethods.toList - - if (self.lifeCycle.isEmpty) self.lifeCycle = Some(LifeCycle(Permanent)) - - // See if we have any config define restart callbacks - restartCallbacks match { - case None => {} - case Some(RestartCallbacks(pre, post)) => - preRestart = Some(try { - targetInstance.getClass.getDeclaredMethod(pre, ZERO_ITEM_CLASS_ARRAY: _*) - } catch { case e => throw new IllegalActorStateException( - "Could not find pre restart method [" + pre + "] \nin [" + - targetClass.getName + "]. \nIt must have a zero argument definition.") }) - postRestart = Some(try { - targetInstance.getClass.getDeclaredMethod(post, ZERO_ITEM_CLASS_ARRAY: _*) - } catch { case e => throw new IllegalActorStateException( - "Could not find post restart method [" + post + "] \nin [" + - targetClass.getName + "]. \nIt must have a zero argument definition.") }) - } - // See if we have any config define a shutdown callback - shutdownCallback match { - case None => {} - case Some(ShutdownCallback(down)) => - zhutdown = Some(try { - targetInstance.getClass.getDeclaredMethod(down, ZERO_ITEM_CLASS_ARRAY: _*) - } catch { case e => throw new IllegalStateException( - "Could not find shutdown method [" + down + "] \nin [" + - targetClass.getName + "]. \nIt must have a zero argument definition.") }) - } - - // See if we have any annotation defined restart callbacks - if (!preRestart.isDefined) preRestart = methods.find(m => m.isAnnotationPresent(Annotations.prerestart)) - if (!postRestart.isDefined) postRestart = methods.find(m => m.isAnnotationPresent(Annotations.postrestart)) - // See if we have an annotation defined shutdown callback - if (!zhutdown.isDefined) zhutdown = methods.find(m => m.isAnnotationPresent(Annotations.shutdown)) - - if (preRestart.isDefined && preRestart.get.getParameterTypes.length != 0) - throw new IllegalActorStateException( - "Method annotated with @prerestart or defined as a restart callback in \n[" + - targetClass.getName + "] must have a zero argument definition") - if (postRestart.isDefined && postRestart.get.getParameterTypes.length != 0) - throw new IllegalActorStateException( - "Method annotated with @postrestart or defined as a restart callback in \n[" + - targetClass.getName + "] must have a zero argument definition") - if (zhutdown.isDefined && zhutdown.get.getParameterTypes.length != 0) - throw new IllegalStateException( - "Method annotated with @shutdown or defined as a shutdown callback in \n[" + - targetClass.getName + "] must have a zero argument definition") - - if (preRestart.isDefined) preRestart.get.setAccessible(true) - if (postRestart.isDefined) postRestart.get.setAccessible(true) - if (zhutdown.isDefined) zhutdown.get.setAccessible(true) - - // see if we have a method annotated with @inittransactionalstate, if so invoke it - initTxState = methods.find(m => m.isAnnotationPresent(Annotations.inittransactionalstate)) - if (initTxState.isDefined && initTxState.get.getParameterTypes.length != 0) - throw new IllegalActorStateException("Method annotated with @inittransactionalstate must have a zero argument definition") - if (initTxState.isDefined) initTxState.get.setAccessible(true) - } - - def receive = { - case invocation @ Invocation(joinPoint, isOneWay, _, sender, senderFuture) => - ActiveObject.log.ifTrace("Invoking active object with message:\n" + invocation) - context.foreach { ctx => - if (sender ne null) ctx._sender = sender - if (senderFuture ne null) ctx._senderFuture = senderFuture - } - ActiveObjectContext.sender.value = joinPoint.getThis // set next sender - self.senderFuture.foreach(ActiveObjectContext.senderFuture.value = _) - if (Actor.SERIALIZE_MESSAGES) serializeArguments(joinPoint) - if (isOneWay) joinPoint.proceed - else self.reply(joinPoint.proceed) - - // Jan Kronquist: started work on issue 121 - case Link(target) => self.link(target) - case Unlink(target) => self.unlink(target) - case unexpected => throw new IllegalActorStateException( - "Unexpected message [" + unexpected + "] sent to [" + this + "]") - } - - override def preRestart(reason: Throwable) { - try { - // Since preRestart is called we know that this dispatcher - // is about to be restarted. Put the instance in a thread - // local so the new dispatcher can be initialized with the - // contents of the old. - //FIXME - This should be considered as a workaround. - crashedActorTl.set(this) - preRestart.foreach(_.invoke(target.get, ZERO_ITEM_OBJECT_ARRAY: _*)) - } catch { case e: InvocationTargetException => throw e.getCause } - } - - override def postRestart(reason: Throwable) { - try { - postRestart.foreach(_.invoke(target.get, ZERO_ITEM_OBJECT_ARRAY: _*)) - } catch { case e: InvocationTargetException => throw e.getCause } - } - - override def init = { - // Get the crashed dispatcher from thread local and intitialize this actor with the - // contents of the old dispatcher - val oldActor = crashedActorTl.get(); - if (oldActor != null) { - initialize(oldActor.targetClass, oldActor.target.get, oldActor.context) - crashedActorTl.set(null) - } - } - - override def shutdown = { - try { - zhutdown.foreach(_.invoke(target.get, ZERO_ITEM_OBJECT_ARRAY: _*)) - } catch { case e: InvocationTargetException => throw e.getCause - } finally { - AspectInitRegistry.unregister(target.get); - } - } - - override def initTransactionalState = { - try { - if (initTxState.isDefined && target.isDefined) initTxState.get.invoke(target.get, ZERO_ITEM_OBJECT_ARRAY: _*) - } catch { case e: InvocationTargetException => throw e.getCause } - } - - private def serializeArguments(joinPoint: JoinPoint) = { - val args = joinPoint.getRtti.asInstanceOf[MethodRtti].getParameterValues - var unserializable = false - var hasMutableArgument = false - for (arg <- args.toList) { - if (!arg.isInstanceOf[String] && - !arg.isInstanceOf[Byte] && - !arg.isInstanceOf[Int] && - !arg.isInstanceOf[Long] && - !arg.isInstanceOf[Float] && - !arg.isInstanceOf[Double] && - !arg.isInstanceOf[Boolean] && - !arg.isInstanceOf[Char] && - !arg.isInstanceOf[java.lang.Byte] && - !arg.isInstanceOf[java.lang.Integer] && - !arg.isInstanceOf[java.lang.Long] && - !arg.isInstanceOf[java.lang.Float] && - !arg.isInstanceOf[java.lang.Double] && - !arg.isInstanceOf[java.lang.Boolean] && - !arg.isInstanceOf[java.lang.Character]) { - hasMutableArgument = true - } - if (arg.getClass.getName.contains(ActiveObject.AW_PROXY_PREFIX)) unserializable = true - } - if (!unserializable && hasMutableArgument) { - val copyOfArgs = Serializer.Java.deepClone(args) - joinPoint.getRtti.asInstanceOf[MethodRtti].setParameterValues(copyOfArgs.asInstanceOf[Array[AnyRef]]) - } - } -} diff --git a/akka-core/src/main/scala/actor/Actor.scala b/akka-core/src/main/scala/actor/Actor.scala index b99ce22a93..1de3997c12 100644 --- a/akka-core/src/main/scala/actor/Actor.scala +++ b/akka-core/src/main/scala/actor/Actor.scala @@ -436,12 +436,12 @@ trait Actor extends Logging { } private val lifeCycles: Receive = { - case HotSwap(code) => become(code) - case Exit(dead, reason) => self.handleTrapExit(dead, reason) - case Link(child) => self.link(child) - case Unlink(child) => self.unlink(child) + case HotSwap(code) => become(code) + case Exit(dead, reason) => self.handleTrapExit(dead, reason) + case Link(child) => self.link(child) + case Unlink(child) => self.unlink(child) case UnlinkAndStop(child) => self.unlink(child); child.stop - case Restart(reason) => throw reason + case Restart(reason) => throw reason } } diff --git a/akka-core/src/main/scala/actor/ActorRef.scala b/akka-core/src/main/scala/actor/ActorRef.scala index 8e233db649..ca55d6c1fa 100644 --- a/akka-core/src/main/scala/actor/ActorRef.scala +++ b/akka-core/src/main/scala/actor/ActorRef.scala @@ -291,15 +291,15 @@ trait ActorRef extends TransactionManagement { def !!(message: Any, timeout: Long = this.timeout)(implicit sender: Option[ActorRef] = None): Option[Any] = { if (isRunning) { val future = postMessageToMailboxAndCreateFutureResultWithTimeout[Any](message, timeout, sender, None) - val isActiveObject = message.isInstanceOf[Invocation] - if (isActiveObject && message.asInstanceOf[Invocation].isVoid) { + val isTypedActor = message.isInstanceOf[Invocation] + if (isTypedActor && message.asInstanceOf[Invocation].isVoid) { future.asInstanceOf[CompletableFuture[Option[_]]].completeWithResult(None) } try { future.await } catch { case e: FutureTimeoutException => - if (isActiveObject) throw e + if (isTypedActor) throw e else None } if (future.exception.isDefined) throw future.exception.get._2 @@ -347,7 +347,7 @@ trait ActorRef extends TransactionManagement { "\n\tNo sender in scope, can't reply. " + "\n\tYou have probably: " + "\n\t\t1. Sent a message to an Actor from an instance that is NOT an Actor." + - "\n\t\t2. Invoked a method on an Active Object from an instance NOT an Active Object." + + "\n\t\t2. Invoked a method on an TypedActor from an instance NOT an TypedActor." + "\n\tElse you might want to use 'reply_?' which returns Boolean(true) if succes and Boolean(false) if no sender in scope") /** @@ -1012,20 +1012,14 @@ sealed class LocalActorRef private[akka]( guard.withGuard { lifeCycle match { case Some(LifeCycle(Temporary, _, _)) => shutDownTemporaryActor(this) - case _ => + case _ => // either permanent or none where default is permanent Actor.log.info("Restarting actor [%s] configured as PERMANENT.", id) Actor.log.debug("Restarting linked actors for actor [%s].", id) restartLinkedActors(reason, maxNrOfRetries, withinTimeRange) Actor.log.debug("Invoking 'preRestart' for failed actor instance [%s].", id) - failedActor.preRestart(reason) - nullOutActorRefReferencesFor(failedActor) - val freshActor = newActor - freshActor.init - freshActor.initTransactionalState - actorInstance.set(freshActor) - Actor.log.debug("Invoking 'postRestart' for new actor instance [%s].", id) - freshActor.postRestart(reason) + if (isTypedActorDispatcher(failedActor)) restartTypedActorDispatcher(failedActor, reason) + else restartActor(failedActor, reason) _isBeingRestarted = false } } @@ -1062,6 +1056,24 @@ sealed class LocalActorRef private[akka]( // ========= PRIVATE FUNCTIONS ========= + private def isTypedActorDispatcher(a: Actor): Boolean = a.isInstanceOf[Dispatcher] + + private def restartTypedActorDispatcher(failedActor: Actor, reason: Throwable) = { + failedActor.preRestart(reason) + failedActor.postRestart(reason) + } + + private def restartActor(failedActor: Actor, reason: Throwable) = { + failedActor.preRestart(reason) + nullOutActorRefReferencesFor(failedActor) + val freshActor = newActor + freshActor.init + freshActor.initTransactionalState + actorInstance.set(freshActor) + Actor.log.debug("Invoking 'postRestart' for new actor instance [%s].", id) + freshActor.postRestart(reason) + } + private def spawnButDoNotStart[T <: Actor: Manifest]: ActorRef = guard.withGuard { val actorRef = Actor.actorOf(manifest[T].erasure.asInstanceOf[Class[T]].newInstance) if (!dispatcher.isInstanceOf[ThreadBasedDispatcher]) actorRef.dispatcher = dispatcher @@ -1102,7 +1114,8 @@ sealed class LocalActorRef private[akka]( createNewTransactionSet } else oldTxSet Actor.log.ifTrace("Joining transaction set [" + currentTxSet + - "];\n\tactor " + toString + "\n\twith message [" + message + "]") + "];\n\tactor " + toString + + "\n\twith message [" + message + "]") val mtx = ThreadLocalTransaction.getThreadLocalTransaction if ((mtx eq null) || mtx.getStatus.isDead) currentTxSet.incParties else currentTxSet.incParties(mtx, 1) @@ -1142,8 +1155,7 @@ sealed class LocalActorRef private[akka]( new TransactionSetAbortedException("Transaction set has been aborted by another participant"), message, topLevelTransaction) case e: InterruptedException => {} // received message while actor is shutting down, ignore - case e => - handleExceptionInDispatch(e, message, topLevelTransaction) + case e => handleExceptionInDispatch(e, message, topLevelTransaction) } finally { clearTransaction if (topLevelTransaction) clearTransactionSet diff --git a/akka-core/src/main/scala/actor/SerializationProtocol.scala b/akka-core/src/main/scala/actor/SerializationProtocol.scala index 13e8230638..3897d3abda 100644 --- a/akka-core/src/main/scala/actor/SerializationProtocol.scala +++ b/akka-core/src/main/scala/actor/SerializationProtocol.scala @@ -122,7 +122,8 @@ object ActorSerialization { private def fromBinaryToLocalActorRef[T <: Actor](bytes: Array[Byte], format: Format[T]): ActorRef = fromProtobufToLocalActorRef(SerializedActorRefProtocol.newBuilder.mergeFrom(bytes).build, format, None) - private def fromProtobufToLocalActorRef[T <: Actor](protocol: SerializedActorRefProtocol, format: Format[T], loader: Option[ClassLoader]): ActorRef = { + private def fromProtobufToLocalActorRef[T <: Actor]( + protocol: SerializedActorRefProtocol, format: Format[T], loader: Option[ClassLoader]): ActorRef = { Actor.log.debug("Deserializing SerializedActorRefProtocol to LocalActorRef:\n" + protocol) val serializer = @@ -225,26 +226,30 @@ object RemoteActorSerialization { .build } - def createRemoteRequestProtocolBuilder(ar: ActorRef, - message: Any, isOneWay: Boolean, senderOption: Option[ActorRef]): RemoteRequestProtocol.Builder = { - import ar._ - val protocol = RemoteRequestProtocol.newBuilder - .setId(RemoteRequestProtocolIdFactory.nextId) - .setMessage(MessageSerializer.serialize(message)) + def createRemoteRequestProtocolBuilder(actorRef: ActorRef, message: Any, isOneWay: Boolean, senderOption: Option[ActorRef]): + RemoteRequestProtocol.Builder = { + import actorRef._ + + val actorInfo = ActorInfoProtocol.newBuilder + .setUuid(uuid) .setTarget(actorClassName) .setTimeout(timeout) - .setUuid(uuid) - .setIsActor(true) + .setActorType(ActorType.SCALA_ACTOR) + .build + + val request = RemoteRequestProtocol.newBuilder + .setId(RemoteRequestProtocolIdFactory.nextId) + .setMessage(MessageSerializer.serialize(message)) + .setActorInfo(actorInfo) .setIsOneWay(isOneWay) - .setIsEscaped(false) val id = registerSupervisorAsRemoteActor - if (id.isDefined) protocol.setSupervisorUuid(id.get) + if (id.isDefined) request.setSupervisorUuid(id.get) senderOption.foreach { sender => RemoteServer.getOrCreateServer(sender.homeAddress).register(sender.uuid, sender) - protocol.setSender(toRemoteActorRefProtocol(sender)) + request.setSender(toRemoteActorRefProtocol(sender)) } - protocol + request } } diff --git a/akka-core/src/main/scala/actor/TypedActor.scala b/akka-core/src/main/scala/actor/TypedActor.scala new file mode 100644 index 0000000000..de204bab5b --- /dev/null +++ b/akka-core/src/main/scala/actor/TypedActor.scala @@ -0,0 +1,839 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +import Actor._ +import se.scalablesolutions.akka.config.FaultHandlingStrategy +import se.scalablesolutions.akka.remote.protocol.RemoteProtocol._ +import se.scalablesolutions.akka.remote.{MessageSerializer, RemoteClient, RemoteRequestProtocolIdFactory} +import se.scalablesolutions.akka.dispatch.{MessageDispatcher, Future, CompletableFuture} +import se.scalablesolutions.akka.config.ScalaConfig._ +import se.scalablesolutions.akka.serialization.Serializer +import se.scalablesolutions.akka.util._ +import se.scalablesolutions.akka.actor.annotation._ + +import org.codehaus.aspectwerkz.joinpoint.{MethodRtti, JoinPoint} +import org.codehaus.aspectwerkz.proxy.Proxy +import org.codehaus.aspectwerkz.annotation.{Aspect, Around} + +import java.net.InetSocketAddress +import java.lang.reflect.{InvocationTargetException, Method, Field} + +import scala.reflect.BeanProperty + +/** + * FIXME: document TypedActor + * + * Here is an example of usage (in Java): + *
+ * class PingImpl extends TypedActor implements Ping {
+ *   public void hit(int count) {
+ *     Pong pong = (Pong) getContext().getSender();
+ *     pong.hit(count++);
+ *   }
+ * 
+ *   @Override
+ *   public void init() {
+ *     ... // optional initialization on start
+ *   }
+ * 
+ *   @Override
+ *   public void shutdown() {
+ *     ... // optional cleanup on stop
+ *   }
+ *
+ *   ... // more life-cycle callbacks if needed
+ * }
+ * 
+ * // create the ping actor
+ * Ping ping = TypedActor.newInstance(Ping.class, PingImpl.class);
+ *
+ * ping.hit(1); // use the actor
+ * ping.hit(1);
+ *
+ * // stop the actor
+ * TypedActor.stop(ping);
+ * 
+ * + * Here is an example of usage (in Scala): + *
+ * class PingImpl extends TypedActor with Ping {
+ *   def hit(count: Int) = {
+ *     val pong = context.sender.asInstanceOf[Pong]
+ *     pong.hit(count += 1)
+ *   }
+ *
+ *   override def init = {
+ *     ... // optional initialization on start
+ *   }
+ * 
+ *   override def shutdown = {
+ *     ... // optional cleanup on stop
+ *   }
+ *
+ *   ... // more life-cycle callbacks if needed
+ * }
+ * 
+ * // create the ping actor
+ * val ping = TypedActor.newInstance(classOf[Ping], classOf[PingImpl])
+ *
+ * ping.hit(1) // use the actor
+ * ping.hit(1)
+ *
+ * // stop the actor
+ * TypedActor.stop(ping)
+ * 
+ * + * @author Jonas Bonér + */ +abstract class TypedActor extends Logging { + + /** + * Holds RTTI (runtime type information) for the TypedActor, f.e. current 'sender' + * reference, the 'senderFuture' reference etc. + *

+ * This class does not contain static information but is updated by the runtime system + * at runtime. + *

+ * You can get a hold of the context using either the 'getContext()' or 'context' + * methods from the 'TypedActor' base class. + *

+ * + * Here is an example of usage (in Java): + *

+   * class PingImpl extends TypedActor implements Ping {
+   *   public void hit(int count) {
+   *     Pong pong = (Pong) getContext().getSender();
+   *     pong.hit(count++);
+   *   }
+   * }
+   * 
+ * + * Here is an example of usage (in Scala): + *
+   * class PingImpl extends TypedActor with Ping {
+   *   def hit(count: Int) = {
+   *     val pong = context.sender.asInstanceOf[Pong]
+   *     pong.hit(count += 1)
+   *   }
+   * }
+   * 
+ */ + @BeanProperty protected var context: TypedActorContext = _ + + /** + * The uuid for the Typed Actor. + */ + @BeanProperty @volatile var uuid = UUID.newUuid.toString + + /** + * Identifier for actor, does not have to be a unique one. Default is the 'uuid'. + *

+ * This field is used for logging, AspectRegistry.actorsFor(id), identifier for remote + * actor in RemoteServer etc.But also as the identifier for persistence, which means + * that you can use a custom name to be able to retrieve the "correct" persisted state + * upon restart, remote restart etc. + *

+ * This property can be set to a custom ID. + */ + @BeanProperty @volatile protected var id: String = uuid + + /** + * Defines the default timeout for '!!' and '!!!' invocations, + * e.g. the timeout for the future returned by the call to '!!' and '!!!'. + *

+ * This property can be set to a custom timeout. + */ + @BeanProperty @volatile protected var timeout: Long = Actor.TIMEOUT + + /** + * User overridable callback. + *

+ * Is called when an Actor is started by invoking 'actor.start'. + */ + def init {} + + /** + * User overridable callback. + *

+ * Is called when 'actor.stop' is invoked. + */ + def shutdown {} + + /** + * User overridable callback. + *

+ * Is called on a crashed Actor right BEFORE it is restarted to allow clean up of resources before Actor is terminated. + */ + def preRestart(reason: Throwable) {} + + /** + * User overridable callback. + *

+ * Is called right AFTER restart on the newly created Actor to allow reinitialization after an Actor crash. + */ + def postRestart(reason: Throwable) {} + + /** + * User overridable callback. + *

+ * Is called during initialization. Can be used to initialize transactional state. Will be invoked within a transaction. + */ + def initTransactionalState {} +} + +/** + * FIXME: document TypedTransactor + * + * @author Jonas Bonér + */ +@transactionrequired +abstract class TypedTransactor extends TypedActor + +/** + * Configuration factory for TypedActors. + * + * FIXDOC: document TypedActorConfiguration + * + * @author Jonas Bonér + */ +final class TypedActorConfiguration { + private[akka] var _timeout: Long = Actor.TIMEOUT + private[akka] var _restartCallbacks: Option[RestartCallbacks] = None + private[akka] var _shutdownCallback: Option[ShutdownCallback] = None + private[akka] var _transactionRequired = false + private[akka] var _host: Option[InetSocketAddress] = None + private[akka] var _messageDispatcher: Option[MessageDispatcher] = None + + def timeout = _timeout + def timeout(timeout: Duration) : TypedActorConfiguration = { + _timeout = timeout.toMillis + this + } + + def restartCallbacks(pre: String, post: String) : TypedActorConfiguration = { + _restartCallbacks = Some(new RestartCallbacks(pre, post)) + this + } + + def shutdownCallback(down: String) : TypedActorConfiguration = { + _shutdownCallback = Some(new ShutdownCallback(down)) + this + } + + def makeTransactionRequired() : TypedActorConfiguration = { + _transactionRequired = true; + this + } + + def makeRemote(hostname: String, port: Int) : TypedActorConfiguration = { + _host = Some(new InetSocketAddress(hostname, port)) + this + } + + def dispatcher(messageDispatcher: MessageDispatcher) : TypedActorConfiguration = { + _messageDispatcher = Some(messageDispatcher) + this + } +} + +/** + * Holds RTTI (runtime type information) for the TypedActor, f.e. current 'sender' + * reference, the 'senderFuture' reference etc. + *

+ * This class does not contain static information but is updated by the runtime system + * at runtime. + *

+ * You can get a hold of the context using either the 'getContext()' or 'context' + * methods from the 'TypedActor' base class. + *

+ * Here is an example of usage (from Java): + *

+ * class PingImpl extends TypedActor implements Ping {
+ *   public void hit(int count) {
+ *     Pong pong = (Pong) getContext().getSender();
+ *     pong.hit(count++);
+ *   }
+ * }
+ * 
+ * + * Here is an example of usage (in Scala): + *
+ * class PingImpl extends TypedActor with Ping {
+ *   def hit(count: Int) = {
+ *     val pong = context.sender.asInstanceOf[Pong]
+ *     pong.hit(count += 1)
+ *   }
+ * }
+ * 
+ * + * @author Jonas Bonér + */ +final class TypedActorContext { + private[akka] var _self: AnyRef = _ + private[akka] var _sender: AnyRef = _ + private[akka] var _senderFuture: CompletableFuture[Any] = _ + + /** + * Returns the current sender reference. + * Scala style getter. + */ + def sender: AnyRef = { + if (_sender eq null) throw new IllegalActorStateException("Sender reference should not be null.") + else _sender + } + + /** + * Returns the current sender reference. + * Java style getter. + */ + def getSender: AnyRef = { + if (_sender eq null) throw new IllegalActorStateException("Sender reference should not be null.") + else _sender + } + + /** + * Returns the current sender future TypedActor reference. + * Scala style getter. + */ + def senderFuture: Option[CompletableFuture[Any]] = if (_senderFuture eq null) None else Some(_senderFuture) + + /** + * Returns the current sender future TypedActor reference. + * Java style getter. + * This method returns 'null' if the sender future is not available. + */ + def getSenderFuture = _senderFuture +} + +/** + * Factory class for creating TypedActors out of plain POJOs and/or POJOs with interfaces. + * + * @author Jonas Bonér + */ +object TypedActor extends Logging { + import Actor.actorOf + + val AKKA_CAMEL_ROUTING_SCHEME = "akka".intern + private[actor] val AW_PROXY_PREFIX = "$$ProxiedByAW".intern + + def newInstance[T](intfClass: Class[T], targetClass: Class[_], timeout: Long): T = { + newInstance(intfClass, newTypedActor(targetClass), actorOf(new Dispatcher(false)), None, timeout) + } + + def newInstance[T](intfClass: Class[T], targetClass: Class[_]): T = { + newInstance(intfClass, newTypedActor(targetClass), actorOf(new Dispatcher(false)), None, Actor.TIMEOUT) + } + + def newRemoteInstance[T](intfClass: Class[T], targetClass: Class[_], timeout: Long, hostname: String, port: Int): T = { + newInstance(intfClass, newTypedActor(targetClass), actorOf(new Dispatcher(false)), Some(new InetSocketAddress(hostname, port)), timeout) + } + + def newRemoteInstance[T](intfClass: Class[T], targetClass: Class[_], hostname: String, port: Int): T = { + newInstance(intfClass, newTypedActor(targetClass), actorOf(new Dispatcher(false)), Some(new InetSocketAddress(hostname, port)), Actor.TIMEOUT) + } + + def newInstance[T](intfClass: Class[T], targetClass: Class[_], config: TypedActorConfiguration): T = { + val actor = actorOf(new Dispatcher(config._transactionRequired)) + if (config._messageDispatcher.isDefined) actor.dispatcher = config._messageDispatcher.get + newInstance(intfClass, newTypedActor(targetClass), actor, config._host, config.timeout) + } + + private[akka] def newInstance[T](intfClass: Class[T], targetInstance: TypedActor, actorRef: ActorRef, + remoteAddress: Option[InetSocketAddress], timeout: Long): T = { + val context = injectTypedActorContext(targetInstance) + val proxy = Proxy.newInstance(Array(intfClass), Array(targetInstance), true, false) + actorRef.actor.asInstanceOf[Dispatcher].initialize(targetInstance.getClass, targetInstance, proxy, context) + actorRef.timeout = timeout + if (remoteAddress.isDefined) actorRef.makeRemote(remoteAddress.get) + AspectInitRegistry.register(proxy, AspectInit(intfClass, targetInstance, actorRef, remoteAddress, timeout)) + actorRef.start + proxy.asInstanceOf[T] + } + + // NOTE: currently not used - but keep it around + private[akka] def newInstance[T <: TypedActor]( + targetClass: Class[T], actorRef: ActorRef, remoteAddress: Option[InetSocketAddress], timeout: Long): T = { + val proxy = { + val instance = Proxy.newInstance(targetClass, true, false) + if (instance.isInstanceOf[TypedActor]) instance.asInstanceOf[TypedActor] + else throw new IllegalActorStateException("Actor [" + targetClass.getName + "] is not a sub class of 'TypedActor'") + } + val context = injectTypedActorContext(proxy) + actorRef.actor.asInstanceOf[Dispatcher].initialize(targetClass, proxy, proxy, context) + actorRef.timeout = timeout + if (remoteAddress.isDefined) actorRef.makeRemote(remoteAddress.get) + AspectInitRegistry.register(proxy, AspectInit(targetClass, proxy, actorRef, remoteAddress, timeout)) + actorRef.start + proxy.asInstanceOf[T] + } + + /** + * Stops the current Typed Actor. + */ + def stop(proxy: AnyRef): Unit = AspectInitRegistry.initFor(proxy).actorRef.stop + + /** + * Get the underlying dispatcher actor for the given Typed Actor. + */ + def actorFor(proxy: AnyRef): Option[ActorRef] = + ActorRegistry.actorsFor(classOf[Dispatcher]).find(a => a.actor.asInstanceOf[Dispatcher].proxy == proxy) + + /** + * Links an other Typed Actor to this Typed Actor. + * @param supervisor the supervisor Typed Actor + * @param supervised the Typed Actor to link + */ + def link(supervisor: AnyRef, supervised: AnyRef) = { + val supervisorActor = actorFor(supervisor).getOrElse( + throw new IllegalActorStateException("Can't link when the supervisor is not an Typed Actor")) + val supervisedActor = actorFor(supervised).getOrElse( + throw new IllegalActorStateException("Can't link when the supervised is not an Typed Actor")) + supervisorActor.link(supervisedActor) + } + + /** + * Links an other Typed Actor to this Typed Actor and sets the fault handling for the supervisor. + * @param supervisor the supervisor Typed Actor + * @param supervised the Typed Actor to link + * @param handler fault handling strategy + * @param trapExceptions array of exceptions that should be handled by the supervisor + */ + def link(supervisor: AnyRef, supervised: AnyRef, + handler: FaultHandlingStrategy, trapExceptions: Array[Class[_ <: Throwable]]) = { + val supervisorActor = actorFor(supervisor).getOrElse( + throw new IllegalActorStateException("Can't link when the supervisor is not an Typed Actor")) + val supervisedActor = actorFor(supervised).getOrElse( + throw new IllegalActorStateException("Can't link when the supervised is not an Typed Actor")) + supervisorActor.trapExit = trapExceptions.toList + supervisorActor.faultHandler = Some(handler) + supervisorActor.link(supervisedActor) + } + + /** + * Unlink the supervised Typed Actor from the supervisor. + * @param supervisor the supervisor Typed Actor + * @param supervised the Typed Actor to unlink + */ + def unlink(supervisor: AnyRef, supervised: AnyRef) = { + val supervisorActor = actorFor(supervisor).getOrElse( + throw new IllegalActorStateException("Can't unlink when the supervisor is not an Typed Actor")) + val supervisedActor = actorFor(supervised).getOrElse( + throw new IllegalActorStateException("Can't unlink when the supervised is not an Typed Actor")) + supervisorActor.unlink(supervisedActor) + } + + /** + * Sets the trap exit for the given supervisor Typed Actor. + * @param supervisor the supervisor Typed Actor + * @param trapExceptions array of exceptions that should be handled by the supervisor + */ + def trapExit(supervisor: AnyRef, trapExceptions: Array[Class[_ <: Throwable]]) = { + val supervisorActor = actorFor(supervisor).getOrElse( + throw new IllegalActorStateException("Can't set trap exceptions when the supervisor is not an Typed Actor")) + supervisorActor.trapExit = trapExceptions.toList + this + } + + /** + * Sets the fault handling strategy for the given supervisor Typed Actor. + * @param supervisor the supervisor Typed Actor + * @param handler fault handling strategy + */ + def faultHandler(supervisor: AnyRef, handler: FaultHandlingStrategy) = { + val supervisorActor = actorFor(supervisor).getOrElse( + throw new IllegalActorStateException("Can't set fault handler when the supervisor is not an Typed Actor")) + supervisorActor.faultHandler = Some(handler) + this + } + + private def injectTypedActorContext(activeObject: AnyRef): Option[TypedActorContext] = { + def injectTypedActorContext0(activeObject: AnyRef, clazz: Class[_]): Option[TypedActorContext] = { + val contextField = clazz.getDeclaredFields.toList.find(_.getType == classOf[TypedActorContext]) + if (contextField.isDefined) { + contextField.get.setAccessible(true) + val context = new TypedActorContext + contextField.get.set(activeObject, context) + Some(context) + } else { + val parent = clazz.getSuperclass + if (parent != null) injectTypedActorContext0(activeObject, parent) + else { + log.ifTrace("Can't set 'TypedActorContext' for TypedActor [" + + activeObject.getClass.getName + + "] since no field of this type could be found.") + None + } + } + } + injectTypedActorContext0(activeObject, activeObject.getClass) + } + + private[akka] def newTypedActor(targetClass: Class[_]): TypedActor = { + val instance = targetClass.newInstance + val typedActor = + if (instance.isInstanceOf[TypedActor]) instance.asInstanceOf[TypedActor] + else throw new IllegalArgumentException("Actor [" + targetClass.getName + "] is not a sub class of 'TypedActor'") + typedActor.init + import se.scalablesolutions.akka.stm.local.atomic + atomic { + typedActor.initTransactionalState + } + typedActor + } + + private[akka] def supervise(restartStrategy: RestartStrategy, components: List[Supervise]): Supervisor = + Supervisor(SupervisorConfig(restartStrategy, components)) +} + +/** + * Internal helper class to help pass the contextual information between threads. + * + * @author Jonas Bonér + */ +private[akka] object TypedActorContext { + import scala.util.DynamicVariable + private[actor] val sender = new DynamicVariable[AnyRef](null) + private[actor] val senderFuture = new DynamicVariable[CompletableFuture[Any]](null) +} + +/** + * @author Jonas Bonér + */ +object Annotations { + val transactionrequired = classOf[transactionrequired] + val prerestart = classOf[prerestart] + val postrestart = classOf[postrestart] + val shutdown = classOf[shutdown] + val inittransactionalstate = classOf[inittransactionalstate] +} + +/** + * @author Jonas Bonér + */ +private[akka] object AspectInitRegistry extends ListenerManagement { + private val initializations = new java.util.concurrent.ConcurrentHashMap[AnyRef, AspectInit] + + def initFor(proxy: AnyRef) = initializations.get(proxy) + + def register(proxy: AnyRef, init: AspectInit) = { + val res = initializations.put(proxy, init) + foreachListener(_ ! AspectInitRegistered(proxy, init)) + res + } + + def unregister(proxy: AnyRef) = { + val res = initializations.remove(proxy) + foreachListener(_ ! AspectInitUnregistered(proxy, res)) + res + } +} + +private[akka] sealed trait AspectInitRegistryEvent +private[akka] case class AspectInitRegistered(proxy: AnyRef, init: AspectInit) extends AspectInitRegistryEvent +private[akka] case class AspectInitUnregistered(proxy: AnyRef, init: AspectInit) extends AspectInitRegistryEvent + +/** + * @author Jonas Bonér + */ +private[akka] sealed case class AspectInit( + val interfaceClass: Class[_], + val targetInstance: TypedActor, + val actorRef: ActorRef, + val remoteAddress: Option[InetSocketAddress], + val timeout: Long) { + def this(interfaceClass: Class[_], targetInstance: TypedActor, actorRef: ActorRef, timeout: Long) = + this(interfaceClass, targetInstance, actorRef, None, timeout) +} + +/** + * AspectWerkz Aspect that is turning POJO into TypedActor. + *

+ * Is deployed on a 'perInstance' basis with the pointcut 'execution(* *.*(..))', + * e.g. all methods on the instance. + * + * @author Jonas Bonér + */ +@Aspect("perInstance") +private[akka] sealed class TypedActorAspect { + @volatile private var isInitialized = false + @volatile private var isStopped = false + private var interfaceClass: Class[_] = _ + private var targetInstance: TypedActor = _ + private var actorRef: ActorRef = _ + private var remoteAddress: Option[InetSocketAddress] = _ + private var timeout: Long = _ + private var uuid: String = _ + @volatile private var instance: TypedActor = _ + + @Around("execution(* *.*(..))") + def invoke(joinPoint: JoinPoint): AnyRef = { + if (!isInitialized) { + val init = AspectInitRegistry.initFor(joinPoint.getThis) + interfaceClass = init.interfaceClass + targetInstance = init.targetInstance + uuid = targetInstance.uuid + actorRef = init.actorRef + remoteAddress = init.remoteAddress + timeout = init.timeout + isInitialized = true + } + dispatch(joinPoint) + } + + private def dispatch(joinPoint: JoinPoint) = { + if (remoteAddress.isDefined) remoteDispatch(joinPoint) + else localDispatch(joinPoint) + } + + private def localDispatch(joinPoint: JoinPoint): AnyRef = { + val rtti = joinPoint.getRtti.asInstanceOf[MethodRtti] + val isOneWay = isVoid(rtti) + val sender = TypedActorContext.sender.value + val senderFuture = TypedActorContext.senderFuture.value + + if (!actorRef.isRunning && !isStopped) { + isStopped = true + joinPoint.proceed + + } else if (isOneWay) { + actorRef ! Invocation(joinPoint, true, true, sender, senderFuture) + null.asInstanceOf[AnyRef] + + } else { + val result = (actorRef !! (Invocation(joinPoint, false, isOneWay, sender, senderFuture), timeout)).as[AnyRef] + if (result.isDefined) result.get + else throw new IllegalActorStateException("No result defined for invocation [" + joinPoint + "]") + } + } + + private def remoteDispatch(joinPoint: JoinPoint): AnyRef = { + val rtti = joinPoint.getRtti.asInstanceOf[MethodRtti] + val isOneWay = isVoid(rtti) + val (message: Array[AnyRef], isEscaped) = escapeArguments(rtti.getParameterValues) + + val typedActorInfo = TypedActorInfoProtocol.newBuilder + .setInterface(interfaceClass.getName) + .setMethod(rtti.getMethod.getName) + .build + + val actorInfo = ActorInfoProtocol.newBuilder + .setUuid(uuid) + .setTarget(targetInstance.getClass.getName) + .setTimeout(timeout) + .setActorType(ActorType.TYPED_ACTOR) + .setTypedActorInfo(typedActorInfo) + .build + + val requestBuilder = RemoteRequestProtocol.newBuilder + .setId(RemoteRequestProtocolIdFactory.nextId) + .setMessage(MessageSerializer.serialize(message)) + .setActorInfo(actorInfo) + .setIsOneWay(isOneWay) + + val id = actorRef.registerSupervisorAsRemoteActor + if (id.isDefined) requestBuilder.setSupervisorUuid(id.get) + + val remoteMessage = requestBuilder.build + + val future = RemoteClient.clientFor(remoteAddress.get).send(remoteMessage, None) + + if (isOneWay) null // for void methods + else { + if (future.isDefined) { + future.get.await + val result = getResultOrThrowException(future.get) + if (result.isDefined) result.get + else throw new IllegalActorStateException("No result returned from call to [" + joinPoint + "]") + } else throw new IllegalActorStateException("No future returned from call to [" + joinPoint + "]") + } + } + + private def getResultOrThrowException[T](future: Future[T]): Option[T] = + if (future.exception.isDefined) { + val (_, cause) = future.exception.get + throw cause + } else future.result + + private def isVoid(rtti: MethodRtti) = rtti.getMethod.getReturnType == java.lang.Void.TYPE + + private def escapeArguments(args: Array[AnyRef]): Tuple2[Array[AnyRef], Boolean] = { + var isEscaped = false + val escapedArgs = for (arg <- args) yield { + val clazz = arg.getClass + if (clazz.getName.contains(TypedActor.AW_PROXY_PREFIX)) { + isEscaped = true + TypedActor.AW_PROXY_PREFIX + clazz.getSuperclass.getName + } else arg + } + (escapedArgs, isEscaped) + } +} + +/** + * Represents a snapshot of the current invocation. + * + * @author Jonas Bonér + */ +@serializable private[akka] case class Invocation( + joinPoint: JoinPoint, isOneWay: Boolean, isVoid: Boolean, sender: AnyRef, senderFuture: CompletableFuture[Any]) { + + override def toString: String = synchronized { + "Invocation [" + + "\n\t\tmethod = " + joinPoint.getRtti.asInstanceOf[MethodRtti].getMethod.getName + " @ " + joinPoint.getTarget.getClass.getName + + "\n\t\tisOneWay = " + isOneWay + + "\n\t\tisVoid = " + isVoid + + "\n\t\tsender = " + sender + + "\n\t\tsenderFuture = " + senderFuture + + "]" + } + + override def hashCode: Int = synchronized { + var result = HashCode.SEED + result = HashCode.hash(result, joinPoint) + result = HashCode.hash(result, isOneWay) + result = HashCode.hash(result, isVoid) + result = HashCode.hash(result, sender) + result = HashCode.hash(result, senderFuture) + result + } + + override def equals(that: Any): Boolean = synchronized { + that != null && + that.isInstanceOf[Invocation] && + that.asInstanceOf[Invocation].joinPoint == joinPoint && + that.asInstanceOf[Invocation].isOneWay == isOneWay && + that.asInstanceOf[Invocation].isVoid == isVoid && + that.asInstanceOf[Invocation].sender == sender && + that.asInstanceOf[Invocation].senderFuture == senderFuture + } +} + +object Dispatcher { + val ZERO_ITEM_CLASS_ARRAY = Array[Class[_]]() + val ZERO_ITEM_OBJECT_ARRAY = Array[Object]() +// var crashedActorTl: ThreadLocal[Dispatcher] = new ThreadLocal(); +} + +/** + * Generic Actor managing Invocation dispatch, transaction and error management. + * + * @author Jonas Bonér + */ +private[akka] class Dispatcher(transactionalRequired: Boolean) extends Actor { + import Dispatcher._ + + private[actor] var proxy: AnyRef = _ + private var context: Option[TypedActorContext] = None + private var targetClass: Class[_] = _ + @volatile private[akka] var targetInstance: TypedActor = _ + private var proxyDelegate: Field = _ + + private[actor] def initialize( + targetClass: Class[_], targetInstance: TypedActor, proxy: AnyRef, ctx: Option[TypedActorContext]) = { + if (transactionalRequired || isTransactional(targetClass)) self.makeTransactionRequired + + self.id = targetClass.getName + this.targetClass = targetClass + this.proxy = proxy + this.targetInstance = targetInstance + this.context = ctx + + proxyDelegate = { + val field = proxy.getClass.getDeclaredField("DELEGATE_0") + field.setAccessible(true) + field + } + + if (self.lifeCycle.isEmpty) self.lifeCycle = Some(LifeCycle(Permanent)) + } + + def receive = { + case invocation @ Invocation(joinPoint, isOneWay, _, sender, senderFuture) => + TypedActor.log.ifTrace("Invoking Typed Actor with message:\n" + invocation) + context.foreach { ctx => + if (sender ne null) ctx._sender = sender + if (senderFuture ne null) ctx._senderFuture = senderFuture + } + TypedActorContext.sender.value = joinPoint.getThis // set next sender + self.senderFuture.foreach(TypedActorContext.senderFuture.value = _) + if (Actor.SERIALIZE_MESSAGES) serializeArguments(joinPoint) + if (isOneWay) joinPoint.proceed + else self.reply(joinPoint.proceed) + + // Jan Kronquist: started work on issue 121 + case Link(proxy) => self.link(proxy) + case Unlink(proxy) => self.unlink(proxy) + case unexpected => throw new IllegalActorStateException( + "Unexpected message [" + unexpected + "] sent to [" + this + "]") + } + + override def preRestart(reason: Throwable) { +// crashedActorTl.set(this) + targetInstance.preRestart(reason) + + // rewrite target instance in Dispatcher and AspectWerkz Proxy + targetInstance = TypedActor.newTypedActor(targetClass) + proxyDelegate.set(proxy, targetInstance) + } + + override def postRestart(reason: Throwable) { + targetInstance.postRestart(reason) + } + + override def init { + // Get the crashed dispatcher from thread local and intitialize this actor with the + // contents of the old dispatcher +// val oldActor = crashedActorTl.get +// if (oldActor != null) { +// initialize(oldActor.targetClass, oldActor.targetInstance, oldActor.proxy, oldActor.context) +// crashedActorTl.set(null) +// } + } + + override def shutdown { + targetInstance.shutdown + AspectInitRegistry.unregister(proxy); + } + + override def initTransactionalState { + targetInstance.initTransactionalState + } + + def isTransactional(clazz: Class[_]): Boolean = + if (clazz == null) false + else if (clazz.isAnnotationPresent(Annotations.transactionrequired)) true + else isTransactional(clazz.getSuperclass) + + private def serializeArguments(joinPoint: JoinPoint) = { + val args = joinPoint.getRtti.asInstanceOf[MethodRtti].getParameterValues + var unserializable = false + var hasMutableArgument = false + for (arg <- args.toList) { + if (!arg.isInstanceOf[String] && + !arg.isInstanceOf[Byte] && + !arg.isInstanceOf[Int] && + !arg.isInstanceOf[Long] && + !arg.isInstanceOf[Float] && + !arg.isInstanceOf[Double] && + !arg.isInstanceOf[Boolean] && + !arg.isInstanceOf[Char] && + !arg.isInstanceOf[java.lang.Byte] && + !arg.isInstanceOf[java.lang.Integer] && + !arg.isInstanceOf[java.lang.Long] && + !arg.isInstanceOf[java.lang.Float] && + !arg.isInstanceOf[java.lang.Double] && + !arg.isInstanceOf[java.lang.Boolean] && + !arg.isInstanceOf[java.lang.Character]) { + hasMutableArgument = true + } + if (arg.getClass.getName.contains(TypedActor.AW_PROXY_PREFIX)) unserializable = true + } + if (!unserializable && hasMutableArgument) { + val copyOfArgs = Serializer.Java.deepClone(args) + joinPoint.getRtti.asInstanceOf[MethodRtti].setParameterValues(copyOfArgs.asInstanceOf[Array[AnyRef]]) + } + } +} diff --git a/akka-core/src/main/scala/actor/UntypedActor.scala b/akka-core/src/main/scala/actor/UntypedActor.scala new file mode 100644 index 0000000000..7e45dee40d --- /dev/null +++ b/akka-core/src/main/scala/actor/UntypedActor.scala @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +/** + * FIXME: document + * + * @author Jonas Bonér + */ +abstract class UntypedActor extends Actor { + protected[akka] var context: Option[ActorContext] = None + + protected def receive = { + case msg => + if (context.isEmpty) { + val ctx = new ActorContext(self) + context = Some(ctx) + onReceive(msg, ctx) + } else onReceive(msg, context.get) + } + + def onReceive(message: Any, context: ActorContext): Unit +} + +/** + * FIXME: document + * + * @author Jonas Bonér + */ +class ActorContext(self: ActorRef) { + +} \ No newline at end of file diff --git a/akka-core/src/main/scala/config/Configuration.scala b/akka-core/src/main/scala/config/Configuration.scala index faa5c912f1..e257c739a9 100644 --- a/akka-core/src/main/scala/config/Configuration.scala +++ b/akka-core/src/main/scala/config/Configuration.scala @@ -5,7 +5,7 @@ package se.scalablesolutions.akka.config /* -import se.scalablesolutions.akka.kernel.{ActiveObject, ActiveObjectProxy} +import se.scalablesolutions.akka.kernel.{TypedActor, TypedActorProxy} import com.google.inject.{AbstractModule} import java.util.{List => JList, ArrayList} import scala.reflect.BeanProperty @@ -55,6 +55,6 @@ class Component(@BeanProperty val intf: Class[_], @BeanProperty val target: Class[_], @BeanProperty val lifeCycle: LifeCycle, @BeanProperty val timeout: Int) extends Server { - def newWorker(proxy: ActiveObjectProxy) = se.scalablesolutions.akka.kernel.Supervise(proxy.server, lifeCycle.transform) + def newWorker(proxy: TypedActorProxy) = se.scalablesolutions.akka.kernel.Supervise(proxy.server, lifeCycle.transform) } */ diff --git a/akka-core/src/main/scala/config/Configurator.scala b/akka-core/src/main/scala/config/Configurator.scala index db92c5f35b..ba7e1f35f2 100644 --- a/akka-core/src/main/scala/config/Configurator.scala +++ b/akka-core/src/main/scala/config/Configurator.scala @@ -6,14 +6,14 @@ package se.scalablesolutions.akka.config import ScalaConfig.{RestartStrategy, Component} -private[akka] trait ActiveObjectConfiguratorBase { +private[akka] trait TypedActorConfiguratorBase { def getExternalDependency[T](clazz: Class[T]): T - def configure(restartStrategy: RestartStrategy, components: List[Component]): ActiveObjectConfiguratorBase + def configure(restartStrategy: RestartStrategy, components: List[Component]): TypedActorConfiguratorBase - def inject: ActiveObjectConfiguratorBase + def inject: TypedActorConfiguratorBase - def supervise: ActiveObjectConfiguratorBase + def supervise: TypedActorConfiguratorBase def reset diff --git a/akka-core/src/main/scala/config/ActiveObjectConfigurator.scala b/akka-core/src/main/scala/config/TypedActorConfigurator.scala similarity index 56% rename from akka-core/src/main/scala/config/ActiveObjectConfigurator.scala rename to akka-core/src/main/scala/config/TypedActorConfigurator.scala index 88e495bbd0..797d52cd70 100644 --- a/akka-core/src/main/scala/config/ActiveObjectConfigurator.scala +++ b/akka-core/src/main/scala/config/TypedActorConfigurator.scala @@ -12,54 +12,55 @@ import java.util.{ArrayList} import com.google.inject._ /** - * Configurator for the Active Objects. Used to do declarative configuration of supervision. - * It also does dependency injection with and into Active Objects using dependency injection + * Configurator for the TypedActors. Used to do declarative configuration of supervision. + * It also does dependency injection with and into TypedActors using dependency injection * frameworks such as Google Guice or Spring. *

- * If you don't want declarative configuration then you should use the ActiveObject + * If you don't want declarative configuration then you should use the TypedActor * factory methods. * * @author Jonas Bonér */ -class ActiveObjectConfigurator { +class TypedActorConfigurator { import scala.collection.JavaConversions._ // TODO: make pluggable once we have f.e a SpringConfigurator - private val INSTANCE = new ActiveObjectGuiceConfigurator + private val INSTANCE = new TypedActorGuiceConfigurator /** - * Returns the a list with all active objects that has been put under supervision for the class specified. + * Returns the a list with all typed actors that has been put under supervision for the class specified. * - * @param clazz the class for the active object - * @return a list with all the active objects for the class + * @param clazz the class for the typed actor + * @return a list with all the typed actors for the class */ - def getInstances[T](clazz: Class[T]): JList[T] = INSTANCE.getInstance(clazz).foldLeft(new ArrayList[T]){ (l, i) => l add i ; l } + def getInstances[T](clazz: Class[T]): JList[T] = + INSTANCE.getInstance(clazz).foldLeft(new ArrayList[T]){ (l, i) => l add i ; l } /** - * Returns the first item in a list of all active objects that has been put under supervision for the class specified. + * Returns the first item in a list of all typed actors that has been put under supervision for the class specified. * - * @param clazz the class for the active object - * @return the active object for the class + * @param clazz the class for the typed actor + * @return the typed actor for the class */ def getInstance[T](clazz: Class[T]): T = INSTANCE.getInstance(clazz).head - def configure(restartStrategy: RestartStrategy, components: Array[Component]): ActiveObjectConfigurator = { + def configure(restartStrategy: RestartStrategy, components: Array[Component]): TypedActorConfigurator = { INSTANCE.configure( restartStrategy.transform, components.toList.asInstanceOf[scala.List[Component]].map(_.transform)) this } - def inject: ActiveObjectConfigurator = { + def inject: TypedActorConfigurator = { INSTANCE.inject this } - def supervise: ActiveObjectConfigurator = { + def supervise: TypedActorConfigurator = { INSTANCE.supervise this } - def addExternalGuiceModule(module: Module): ActiveObjectConfigurator = { + def addExternalGuiceModule(module: Module): TypedActorConfigurator = { INSTANCE.addExternalGuiceModule(module) this } diff --git a/akka-core/src/main/scala/config/ActiveObjectGuiceConfigurator.scala b/akka-core/src/main/scala/config/TypedActorGuiceConfigurator.scala similarity index 73% rename from akka-core/src/main/scala/config/ActiveObjectGuiceConfigurator.scala rename to akka-core/src/main/scala/config/TypedActorGuiceConfigurator.scala index 54174b6030..29efc14082 100644 --- a/akka-core/src/main/scala/config/ActiveObjectGuiceConfigurator.scala +++ b/akka-core/src/main/scala/config/TypedActorGuiceConfigurator.scala @@ -7,7 +7,7 @@ package se.scalablesolutions.akka.config import com.google.inject._ import se.scalablesolutions.akka.config.ScalaConfig._ -import se.scalablesolutions.akka.actor.{Supervisor, ActiveObject, Dispatcher, ActorRef, Actor, IllegalActorStateException} +import se.scalablesolutions.akka.actor.{Supervisor, TypedActor, Dispatcher, ActorRef, Actor, IllegalActorStateException} import se.scalablesolutions.akka.remote.RemoteServer import se.scalablesolutions.akka.util.Logging @@ -17,12 +17,12 @@ import java.net.InetSocketAddress import java.lang.reflect.Method /** - * This is an class for internal usage. Instead use the se.scalablesolutions.akka.config.ActiveObjectConfigurator - * class for creating ActiveObjects. + * This is an class for internal usage. Instead use the se.scalablesolutions.akka.config.TypedActorConfigurator + * class for creating TypedActors. * * @author Jonas Bonér */ -private[akka] class ActiveObjectGuiceConfigurator extends ActiveObjectConfiguratorBase with Logging { +private[akka] class TypedActorGuiceConfigurator extends TypedActorConfiguratorBase with Logging { private var injector: Injector = _ private var supervisor: Option[Supervisor] = None private var restartStrategy: RestartStrategy = _ @@ -37,11 +37,11 @@ private[akka] class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurat /** * Returns the active abject that has been put under supervision for the class specified. * - * @param clazz the class for the active object - * @return the active objects for the class + * @param clazz the class for the typed actor + * @return the typed actors for the class */ def getInstance[T](clazz: Class[T]): List[T] = synchronized { - log.debug("Retrieving active object [%s]", clazz.getName) + log.debug("Retrieving typed actor [%s]", clazz.getName) if (injector eq null) throw new IllegalActorStateException( "inject() and/or supervise() must be called before invoking getInstance(clazz)") val (proxy, targetInstance, component) = @@ -67,7 +67,7 @@ private[akka] class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurat } override def configure(restartStrategy: RestartStrategy, components: List[Component]): - ActiveObjectConfiguratorBase = synchronized { + TypedActorConfiguratorBase = synchronized { this.restartStrategy = restartStrategy this.components = components.toArray.toList.asInstanceOf[List[Component]] bindings = for (component <- this.components) yield { @@ -76,56 +76,65 @@ private[akka] class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurat } val deps = new java.util.ArrayList[DependencyBinding](bindings.size) for (b <- bindings) deps.add(b) - modules.add(new ActiveObjectGuiceModule(deps)) + modules.add(new TypedActorGuiceModule(deps)) this } private def newSubclassingProxy(component: Component): DependencyBinding = { - val targetClass = component.target - val actorRef = Actor.actorOf(new Dispatcher(component.transactionRequired, - component.lifeCycle.restartCallbacks, - component.lifeCycle.shutdownCallback)) + val targetClass = + if (component.target.isInstanceOf[Class[_ <: TypedActor]]) component.target.asInstanceOf[Class[_ <: TypedActor]] + else throw new IllegalArgumentException("TypedActor [" + component.target.getName + "] must be a subclass of TypedActor") + val actorRef = Actor.actorOf(new Dispatcher(component.transactionRequired)) if (component.dispatcher.isDefined) actorRef.dispatcher = component.dispatcher.get val remoteAddress = if (component.remoteAddress.isDefined) Some(new InetSocketAddress(component.remoteAddress.get.hostname, component.remoteAddress.get.port)) else None - val proxy = ActiveObject.newInstance(targetClass, actorRef, remoteAddress, component.timeout).asInstanceOf[AnyRef] - remoteAddress.foreach(address => RemoteServer.registerActiveObject(address, targetClass.getName, proxy)) + val proxy = TypedActor.newInstance(targetClass, actorRef, remoteAddress, component.timeout).asInstanceOf[AnyRef] + remoteAddress.foreach(address => RemoteServer.registerTypedActor(address, targetClass.getName, proxy)) supervised ::= Supervise(actorRef, component.lifeCycle) activeObjectRegistry.put(targetClass, (proxy, proxy, component)) new DependencyBinding(targetClass, proxy) } private def newDelegatingProxy(component: Component): DependencyBinding = { - val targetClass = component.intf.get - val targetInstance = component.target.newInstance.asInstanceOf[AnyRef] // TODO: perhaps need to put in registry component.target.getConstructor(Array[Class[_]](): _*).setAccessible(true) - val actorRef = Actor.actorOf(new Dispatcher(component.transactionRequired, - component.lifeCycle.restartCallbacks, - component.lifeCycle.shutdownCallback)) + + val targetClass = component.intf.get + val instance = component.target.newInstance.asInstanceOf[AnyRef] // TODO: perhaps need to put in registry + + val targetInstance = + if (instance.isInstanceOf[TypedActor]) instance.asInstanceOf[TypedActor] + else throw new IllegalArgumentException("TypedActor [" + component.target.getName + "] must be a subclass of TypedActor") + + val actorRef = Actor.actorOf(new Dispatcher(component.transactionRequired)) + if (component.dispatcher.isDefined) actorRef.dispatcher = component.dispatcher.get + val remoteAddress = if (component.remoteAddress.isDefined) Some(new InetSocketAddress(component.remoteAddress.get.hostname, component.remoteAddress.get.port)) else None - val proxy = ActiveObject.newInstance( + + val proxy = TypedActor.newInstance( targetClass, targetInstance, actorRef, remoteAddress, component.timeout).asInstanceOf[AnyRef] - remoteAddress.foreach(address => RemoteServer.registerActiveObject(address, targetClass.getName, proxy)) + + remoteAddress.foreach(address => RemoteServer.registerTypedActor(address, targetClass.getName, proxy)) supervised ::= Supervise(actorRef, component.lifeCycle) + activeObjectRegistry.put(targetClass, (proxy, targetInstance, component)) new DependencyBinding(targetClass, proxy) } - override def inject: ActiveObjectConfiguratorBase = synchronized { + override def inject: TypedActorConfiguratorBase = synchronized { if (injector ne null) throw new IllegalActorStateException("inject() has already been called on this configurator") injector = Guice.createInjector(modules) this } - override def supervise: ActiveObjectConfiguratorBase = synchronized { + override def supervise: TypedActorConfiguratorBase = synchronized { if (injector eq null) inject - supervisor = Some(ActiveObject.supervise(restartStrategy, supervised)) + supervisor = Some(TypedActor.supervise(restartStrategy, supervised)) this } @@ -141,7 +150,7 @@ private[akka] class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurat * }}) * */ - def addExternalGuiceModule(module: Module): ActiveObjectConfiguratorBase = synchronized { + def addExternalGuiceModule(module: Module): TypedActorConfiguratorBase = synchronized { modules.add(module) this } diff --git a/akka-core/src/main/scala/remote/RemoteClient.scala b/akka-core/src/main/scala/remote/RemoteClient.scala index 2936b73b67..a08348e461 100644 --- a/akka-core/src/main/scala/remote/RemoteClient.scala +++ b/akka-core/src/main/scala/remote/RemoteClient.scala @@ -137,7 +137,7 @@ object RemoteClient extends Logging { actorsFor(RemoteServer.Address(hostname, port)) += uuid } - // TODO: add RemoteClient.unregister for ActiveObject, but first need a @shutdown callback + // TODO: add RemoteClient.unregister for TypedActor, but first need a @shutdown callback private[akka] def unregister(hostname: String, port: Int, uuid: String) = synchronized { val set = actorsFor(RemoteServer.Address(hostname, port)) set -= uuid @@ -217,7 +217,7 @@ class RemoteClient private[akka] (val hostname: String, val port: Int, loader: O } else { futures.synchronized { val futureResult = if (senderFuture.isDefined) senderFuture.get - else new DefaultCompletableFuture[T](request.getTimeout) + else new DefaultCompletableFuture[T](request.getActorInfo.getTimeout) futures.put(request.getId, futureResult) connection.getChannel.write(request) Some(futureResult) @@ -230,11 +230,13 @@ class RemoteClient private[akka] (val hostname: String, val port: Int, loader: O } private[akka] def registerSupervisorForActor(actorRef: ActorRef) = - if (!actorRef.supervisor.isDefined) throw new IllegalActorStateException("Can't register supervisor for " + actorRef + " since it is not under supervision") + if (!actorRef.supervisor.isDefined) throw new IllegalActorStateException( + "Can't register supervisor for " + actorRef + " since it is not under supervision") else supervisors.putIfAbsent(actorRef.supervisor.get.uuid, actorRef) private[akka] def deregisterSupervisorForActor(actorRef: ActorRef) = - if (!actorRef.supervisor.isDefined) throw new IllegalActorStateException("Can't unregister supervisor for " + actorRef + " since it is not under supervision") + if (!actorRef.supervisor.isDefined) throw new IllegalActorStateException( + "Can't unregister supervisor for " + actorRef + " since it is not under supervision") else supervisors.remove(actorRef.supervisor.get.uuid) } diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index c3f5cc4f0a..e93fc4db48 100644 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -55,7 +55,7 @@ object RemoteNode extends RemoteServer /** * For internal use only. - * Holds configuration variables, remote actors, remote active objects and remote servers. + * Holds configuration variables, remote actors, remote typed actors and remote servers. * * @author Jonas Bonér */ @@ -104,7 +104,7 @@ object RemoteServer { actorsFor(RemoteServer.Address(address.getHostName, address.getPort)).actors.put(uuid, actor) } - private[akka] def registerActiveObject(address: InetSocketAddress, name: String, activeObject: AnyRef) = guard.withWriteGuard { + private[akka] def registerTypedActor(address: InetSocketAddress, name: String, activeObject: AnyRef) = guard.withWriteGuard { actorsFor(RemoteServer.Address(address.getHostName, address.getPort)).activeObjects.put(name, activeObject) } @@ -228,7 +228,7 @@ class RemoteServer extends Logging { } } - // TODO: register active object in RemoteServer as well + // TODO: register typed actor in RemoteServer as well /** * Register Remote Actor by the Actor's 'id' field. It starts the Actor if it is not started already. @@ -360,139 +360,88 @@ class RemoteServerHandler( private def handleRemoteRequestProtocol(request: RemoteRequestProtocol, channel: Channel) = { log.debug("Received RemoteRequestProtocol[\n%s]", request.toString) - if (request.getIsActor) dispatchToActor(request, channel) - else dispatchToActiveObject(request, channel) + val actorType = request.getActorInfo.getActorType + if (actorType == ActorType.SCALA_ACTOR) dispatchToActor(request, channel) + else if (actorType == ActorType.JAVA_ACTOR) throw new IllegalActorStateException("ActorType JAVA_ACTOR is currently not supported") + else if (actorType == ActorType.TYPED_ACTOR) dispatchToTypedActor(request, channel) + else throw new IllegalActorStateException("Unknown ActorType [" + actorType + "]") } private def dispatchToActor(request: RemoteRequestProtocol, channel: Channel) = { - log.debug("Dispatching to remote actor [%s:%s]", request.getTarget, request.getUuid) - val actorRef = createActor(request.getTarget, request.getUuid, request.getTimeout) + val actorInfo = request.getActorInfo + log.debug("Dispatching to remote actor [%s:%s]", actorInfo.getTarget, actorInfo.getUuid) + + val actorRef = createActor(actorInfo) actorRef.start + val message = MessageSerializer.deserialize(request.getMessage) val sender = if (request.hasSender) Some(RemoteActorSerialization.fromProtobufToRemoteActorRef(request.getSender, applicationLoader)) else None + if (request.getIsOneWay) actorRef.!(message)(sender) else { try { val resultOrNone = (actorRef.!!(message)(sender)).as[AnyRef] val result = if (resultOrNone.isDefined) resultOrNone.get else null + log.debug("Returning result from actor invocation [%s]", result) val replyBuilder = RemoteReplyProtocol.newBuilder .setId(request.getId) .setMessage(MessageSerializer.serialize(result)) .setIsSuccessful(true) .setIsActor(true) + if (request.hasSupervisorUuid) replyBuilder.setSupervisorUuid(request.getSupervisorUuid) - val replyMessage = replyBuilder.build - channel.write(replyMessage) + channel.write(replyBuilder.build) + } catch { - case e: Throwable => - log.error(e, "Could not invoke remote actor [%s]", request.getTarget) - val replyBuilder = RemoteReplyProtocol.newBuilder - .setId(request.getId) - .setException(ExceptionProtocol.newBuilder.setClassname(e.getClass.getName).setMessage(e.getMessage).build) - .setIsSuccessful(false) - .setIsActor(true) - if (request.hasSupervisorUuid) replyBuilder.setSupervisorUuid(request.getSupervisorUuid) - val replyMessage = replyBuilder.build - channel.write(replyMessage) + case e: Throwable => channel.write(createErrorReplyMessage(e, request, true)) } } } - private def dispatchToActiveObject(request: RemoteRequestProtocol, channel: Channel) = { - log.debug("Dispatching to remote active object [%s :: %s]", request.getMethod, request.getTarget) - val activeObject = createActiveObject(request.getTarget, request.getTimeout) + private def dispatchToTypedActor(request: RemoteRequestProtocol, channel: Channel) = { + val actorInfo = request.getActorInfo + val typedActorInfo = actorInfo.getTypedActorInfo + log.debug("Dispatching to remote typed actor [%s :: %s]", typedActorInfo.getMethod, typedActorInfo.getInterface) + val activeObject = createTypedActor(actorInfo) val args = MessageSerializer.deserialize(request.getMessage).asInstanceOf[Array[AnyRef]].toList val argClasses = args.map(_.getClass) - val (unescapedArgs, unescapedArgClasses) = unescapeArgs(args, argClasses, request.getTimeout) try { - val messageReceiver = activeObject.getClass.getDeclaredMethod( - request.getMethod, unescapedArgClasses: _*) - if (request.getIsOneWay) messageReceiver.invoke(activeObject, unescapedArgs: _*) + val messageReceiver = activeObject.getClass.getDeclaredMethod(typedActorInfo.getMethod, argClasses: _*) + if (request.getIsOneWay) messageReceiver.invoke(activeObject, args: _*) else { - val result = messageReceiver.invoke(activeObject, unescapedArgs: _*) - log.debug("Returning result from remote active object invocation [%s]", result) + val result = messageReceiver.invoke(activeObject, args: _*) + log.debug("Returning result from remote typed actor invocation [%s]", result) val replyBuilder = RemoteReplyProtocol.newBuilder .setId(request.getId) .setMessage(MessageSerializer.serialize(result)) .setIsSuccessful(true) .setIsActor(false) if (request.hasSupervisorUuid) replyBuilder.setSupervisorUuid(request.getSupervisorUuid) - val replyMessage = replyBuilder.build - channel.write(replyMessage) + channel.write(replyBuilder.build) } } catch { - case e: InvocationTargetException => - log.error(e.getCause, "Could not invoke remote active object [%s :: %s]", request.getMethod, request.getTarget) - val replyBuilder = RemoteReplyProtocol.newBuilder - .setId(request.getId) - .setException(ExceptionProtocol.newBuilder.setClassname(e.getCause.getClass.getName).setMessage(e.getCause.getMessage).build) - .setIsSuccessful(false) - .setIsActor(false) - if (request.hasSupervisorUuid) replyBuilder.setSupervisorUuid(request.getSupervisorUuid) - val replyMessage = replyBuilder.build - channel.write(replyMessage) - case e: Throwable => - log.error(e, "Could not invoke remote active object [%s :: %s]", request.getMethod, request.getTarget) - val replyBuilder = RemoteReplyProtocol.newBuilder - .setId(request.getId) - .setException(ExceptionProtocol.newBuilder.setClassname(e.getClass.getName).setMessage(e.getMessage).build) - .setIsSuccessful(false) - .setIsActor(false) - if (request.hasSupervisorUuid) replyBuilder.setSupervisorUuid(request.getSupervisorUuid) - val replyMessage = replyBuilder.build - channel.write(replyMessage) + case e: InvocationTargetException => channel.write(createErrorReplyMessage(e.getCause, request, false)) + case e: Throwable => channel.write(createErrorReplyMessage(e, request, false)) } } - private def unescapeArgs(args: scala.List[AnyRef], argClasses: scala.List[Class[_]], timeout: Long) = { - val unescapedArgs = new Array[AnyRef](args.size) - val unescapedArgClasses = new Array[Class[_]](args.size) - - val escapedArgs = for (i <- 0 until args.size) { - val arg = args(i) - if (arg.isInstanceOf[String] && arg.asInstanceOf[String].startsWith(AW_PROXY_PREFIX)) { - val argString = arg.asInstanceOf[String] - val proxyName = argString.replace(AW_PROXY_PREFIX, "") - val activeObject = createActiveObject(proxyName, timeout) - unescapedArgs(i) = activeObject - unescapedArgClasses(i) = Class.forName(proxyName) - } else { - unescapedArgs(i) = args(i) - unescapedArgClasses(i) = argClasses(i) - } - } - (unescapedArgs, unescapedArgClasses) - } - - private def createActiveObject(name: String, timeout: Long): AnyRef = { - val activeObjectOrNull = activeObjects.get(name) - if (activeObjectOrNull eq null) { - try { - log.info("Creating a new remote active object [%s]", name) - val clazz = if (applicationLoader.isDefined) applicationLoader.get.loadClass(name) - else Class.forName(name) - val newInstance = ActiveObject.newInstance(clazz, timeout).asInstanceOf[AnyRef] - activeObjects.put(name, newInstance) - newInstance - } catch { - case e => - log.error(e, "Could not create remote active object instance") - throw e - } - } else activeObjectOrNull - } - /** * Creates a new instance of the actor with name, uuid and timeout specified as arguments. + * * If actor already created then just return it from the registry. + * * Does not start the actor. */ - private def createActor(name: String, uuid: String, timeout: Long): ActorRef = { + private def createActor(actorInfo: ActorInfoProtocol): ActorRef = { + val name = actorInfo.getTarget + val uuid = actorInfo.getUuid + val timeout = actorInfo.getTimeout + val actorRefOrNull = actors.get(uuid) if (actorRefOrNull eq null) { try { @@ -512,4 +461,43 @@ class RemoteServerHandler( } } else actorRefOrNull } + + private def createTypedActor(actorInfo: ActorInfoProtocol): AnyRef = { + val uuid = actorInfo.getUuid + val activeObjectOrNull = activeObjects.get(uuid) + + if (activeObjectOrNull eq null) { + val typedActorInfo = actorInfo.getTypedActorInfo + val interfaceClassname = typedActorInfo.getInterface + val targetClassname = actorInfo.getTarget + + try { + log.info("Creating a new remote typed actor:\n\t[%s :: %s]", interfaceClassname, targetClassname) + + val (interfaceClass, targetClass) = + if (applicationLoader.isDefined) (applicationLoader.get.loadClass(interfaceClassname), + applicationLoader.get.loadClass(targetClassname)) + else (Class.forName(interfaceClassname), Class.forName(targetClassname)) + + val newInstance = TypedActor.newInstance( + interfaceClass, targetClass.asInstanceOf[Class[_ <: TypedActor]], actorInfo.getTimeout).asInstanceOf[AnyRef] + activeObjects.put(uuid, newInstance) + newInstance + } catch { + case e => log.error(e, "Could not create remote typed actor instance"); throw e + } + } else activeObjectOrNull + } + + private def createErrorReplyMessage(e: Throwable, request: RemoteRequestProtocol, isActor: Boolean): RemoteReplyProtocol = { + val actorInfo = request.getActorInfo + log.error(e, "Could not invoke remote typed actor [%s :: %s]", actorInfo.getTypedActorInfo.getMethod, actorInfo.getTarget) + val replyBuilder = RemoteReplyProtocol.newBuilder + .setId(request.getId) + .setException(ExceptionProtocol.newBuilder.setClassname(e.getClass.getName).setMessage(e.getMessage).build) + .setIsSuccessful(false) + .setIsActor(isActor) + if (request.hasSupervisorUuid) replyBuilder.setSupervisorUuid(request.getSupervisorUuid) + replyBuilder.build + } } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/ActiveObjectFailer.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/ActiveObjectFailer.java deleted file mode 100644 index 6e30a1a971..0000000000 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/ActiveObjectFailer.java +++ /dev/null @@ -1,7 +0,0 @@ -package se.scalablesolutions.akka.actor; - -public class ActiveObjectFailer implements java.io.Serializable { - public int fail() { - throw new RuntimeException("expected"); - } -} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java index 09b50a7347..9cb41a85cf 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java @@ -1,13 +1,16 @@ package se.scalablesolutions.akka.actor; import com.google.inject.Inject; +import se.scalablesolutions.akka.actor.*; -public class BarImpl implements Bar { +public class BarImpl extends TypedActor implements Bar { @Inject private Ext ext; + public Ext getExt() { return ext; } + public void bar(String msg) { } } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java index 87eb809aba..4cc5b977dc 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java @@ -1,34 +1,14 @@ package se.scalablesolutions.akka.actor; -import com.google.inject.Inject; - -public class Foo extends se.scalablesolutions.akka.serialization.Serializable.JavaJSON { - @Inject - private Bar bar; - public Foo body() { return this; } - public Bar getBar() { - return bar; - } - public String foo(String msg) { - return msg + "return_foo "; - } - public void bar(String msg) { - bar.bar(msg); - } - public String longRunning() { - try { - Thread.sleep(1200); - } catch (InterruptedException e) { - } - return "test"; - } - public String throwsException() { - if (true) throw new RuntimeException("Expected exception; to test fault-tolerance"); - return "test"; - } +public interface Foo { + public Foo body(); + public Bar getBar(); - public int $tag() throws java.rmi.RemoteException - { - return 0; - } + public String foo(String msg); + public void bar(String msg); + + public String longRunning(); + public String throwsException(); + + public int $tag() throws java.rmi.RemoteException; } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/FooImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/FooImpl.java new file mode 100644 index 0000000000..dc6aba481c --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/FooImpl.java @@ -0,0 +1,40 @@ +package se.scalablesolutions.akka.actor; + +import com.google.inject.Inject; +import se.scalablesolutions.akka.actor.*; + +public class FooImpl extends TypedActor implements Foo { + @Inject + private Bar bar; + + public Foo body() { return this; } + + public Bar getBar() { + return bar; + } + + public String foo(String msg) { + return msg + "return_foo "; + } + + public void bar(String msg) { + bar.bar(msg); + } + + public String longRunning() { + try { + Thread.sleep(1200); + } catch (InterruptedException e) { + } + return "test"; + } + + public String throwsException() { + if (true) throw new RuntimeException("Expected exception; to test fault-tolerance"); + return "test"; + } + + public int $tag() throws java.rmi.RemoteException { + return 0; + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalTypedActor.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalTypedActor.java new file mode 100644 index 0000000000..ee7998f69a --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalTypedActor.java @@ -0,0 +1,12 @@ +package se.scalablesolutions.akka.actor; + +public interface NestedTransactionalTypedActor { + public String getMapState(String key); + public String getVectorState(); + public String getRefState(); + public void setMapState(String key, String msg); + public void setVectorState(String msg); + public void setRefState(String msg); + public void success(String key, String msg); + public String failure(String key, String msg, TypedActorFailer failer); +} \ No newline at end of file diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalActiveObject.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalTypedActorImpl.java similarity index 61% rename from akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalActiveObject.java rename to akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalTypedActorImpl.java index af6bb8245c..699f33785d 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalActiveObject.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalTypedActorImpl.java @@ -1,17 +1,15 @@ package se.scalablesolutions.akka.actor; -import se.scalablesolutions.akka.actor.annotation.transactionrequired; -import se.scalablesolutions.akka.actor.annotation.inittransactionalstate; +import se.scalablesolutions.akka.actor.*; import se.scalablesolutions.akka.stm.*; -@transactionrequired -public class NestedTransactionalActiveObject { +public class NestedTransactionalTypedActorImpl extends TypedTransactor implements NestedTransactionalTypedActor { private TransactionalMap mapState; private TransactionalVector vectorState; private Ref refState; private boolean isInitialized = false; - @inittransactionalstate + @Override public void init() { if (!isInitialized) { mapState = new TransactionalMap(); @@ -25,62 +23,37 @@ public class NestedTransactionalActiveObject { return (String) mapState.get(key).get(); } - public String getVectorState() { return (String) vectorState.last(); } - public String getRefState() { return (String) refState.get().get(); } - public void setMapState(String key, String msg) { mapState.put(key, msg); } - public void setVectorState(String msg) { vectorState.add(msg); } - public void setRefState(String msg) { refState.swap(msg); } - public void success(String key, String msg) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); } - - public String failure(String key, String msg, ActiveObjectFailer failer) { + public String failure(String key, String msg, TypedActorFailer failer) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); failer.fail(); return msg; } - - - public void thisMethodHangs(String key, String msg, ActiveObjectFailer failer) { - setMapState(key, msg); - } - - /* - public void clashOk(String key, String msg, InMemClasher clasher) { - mapState.put(key, msg); - clasher.clash(); - } - - public void clashNotOk(String key, String msg, InMemClasher clasher) { - mapState.put(key, msg); - clasher.clash(); - this.success("clash", "clash"); - } - */ } \ No newline at end of file diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojo.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojo.java index 50f3e43221..ae47276ba6 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojo.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojo.java @@ -2,36 +2,7 @@ package se.scalablesolutions.akka.actor; import java.util.concurrent.CountDownLatch; -public class SamplePojo { - - private CountDownLatch latch; - - public boolean _pre = false; - public boolean _post = false; - public boolean _down = false; - - public CountDownLatch newCountdownLatch(int count) { - latch = new CountDownLatch(count); - return latch; - } - - public String fail() { - throw new RuntimeException("expected"); - } - - public void pre() { - _pre = true; - latch.countDown(); - } - - public void post() { - _post = true; - latch.countDown(); - } - - public void down() { - _down = true; - latch.countDown(); - } - -} +public interface SamplePojo { + public String greet(String s); + public String fail(); +} \ No newline at end of file diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoAnnotated.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoAnnotated.java deleted file mode 100644 index 8bf4ba36d3..0000000000 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoAnnotated.java +++ /dev/null @@ -1,52 +0,0 @@ -package se.scalablesolutions.akka.actor; - -import se.scalablesolutions.akka.actor.annotation.postrestart; -import se.scalablesolutions.akka.actor.annotation.prerestart; -import se.scalablesolutions.akka.actor.annotation.shutdown; - -import java.util.concurrent.CountDownLatch; - -public class SamplePojoAnnotated { - - private CountDownLatch latch; - - public boolean _pre = false; - public boolean _post = false; - public boolean _down = false; - - public SamplePojoAnnotated() { - latch = new CountDownLatch(1); - } - - public CountDownLatch newCountdownLatch(int count) { - latch = new CountDownLatch(count); - return latch; - } - - public String greet(String s) { - return "hello " + s; - } - - public String fail() { - throw new RuntimeException("expected"); - } - - @prerestart - public void pre() { - _pre = true; - latch.countDown(); - } - - @postrestart - public void post() { - _post = true; - latch.countDown(); - } - - @shutdown - public void down() { - _down = true; - latch.countDown(); - } - -} \ No newline at end of file diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoImpl.java new file mode 100644 index 0000000000..d57232b629 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoImpl.java @@ -0,0 +1,45 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.*; + +import java.util.concurrent.CountDownLatch; + +public class SamplePojoImpl extends TypedActor implements SamplePojo { + + public static CountDownLatch latch = new CountDownLatch(1); + + public static boolean _pre = false; + public static boolean _post = false; + public static boolean _down = false; + public static void reset() { + _pre = false; + _post = false; + _down = false; + } + + public String greet(String s) { + return "hello " + s; + } + + public String fail() { + throw new RuntimeException("expected"); + } + + @Override + public void preRestart(Throwable e) { + _pre = true; + latch.countDown(); + } + + @Override + public void postRestart(Throwable e) { + _post = true; + latch.countDown(); + } + + @Override + public void shutdown() { + _down = true; + latch.countDown(); + } +} \ No newline at end of file diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java index 31f22c217f..d7ab60b676 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java @@ -1,48 +1,11 @@ package se.scalablesolutions.akka.actor; -import se.scalablesolutions.akka.actor.annotation.prerestart; -import se.scalablesolutions.akka.actor.annotation.postrestart; -import se.scalablesolutions.akka.actor.ActiveObjectContext; import se.scalablesolutions.akka.dispatch.CompletableFuture; -public class SimpleJavaPojo { - - ActiveObjectContext context; - - public boolean pre = false; - public boolean post = false; - - private String name; - - public Object getSender() { - return context.getSender(); - } - - public CompletableFuture getSenderFuture() { - return context.getSenderFuture(); - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @prerestart - public void pre() { - System.out.println("** pre()"); - pre = true; - } - - @postrestart - public void post() { - System.out.println("** post()"); - post = true; - } - - public void throwException() { - throw new RuntimeException(); - } +public interface SimpleJavaPojo { + public Object getSender(); + public CompletableFuture getSenderFuture(); + public void setName(String name); + public String getName(); + public void throwException(); } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoCaller.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoCaller.java index 0fb6aff9c5..a1bdab5337 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoCaller.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoCaller.java @@ -2,19 +2,8 @@ package se.scalablesolutions.akka.actor; import se.scalablesolutions.akka.dispatch.CompletableFuture; -public class SimpleJavaPojoCaller { - - SimpleJavaPojo pojo; - - public void setPojo(SimpleJavaPojo pojo) { - this.pojo = pojo; - } - - public Object getSenderFromSimpleJavaPojo() { - return pojo.getSender(); - } - - public CompletableFuture getSenderFutureFromSimpleJavaPojo() { - return pojo.getSenderFuture(); - } +public interface SimpleJavaPojoCaller { + public void setPojo(SimpleJavaPojo pojo); + public Object getSenderFromSimpleJavaPojo(); + public CompletableFuture getSenderFutureFromSimpleJavaPojo(); } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoCallerImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoCallerImpl.java new file mode 100644 index 0000000000..15a6aec8e0 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoCallerImpl.java @@ -0,0 +1,21 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.*; +import se.scalablesolutions.akka.dispatch.CompletableFuture; + +public class SimpleJavaPojoCallerImpl extends TypedActor implements SimpleJavaPojoCaller { + + SimpleJavaPojo pojo; + + public void setPojo(SimpleJavaPojo pojo) { + this.pojo = pojo; + } + + public Object getSenderFromSimpleJavaPojo() { + return pojo.getSender(); + } + + public CompletableFuture getSenderFutureFromSimpleJavaPojo() { + return pojo.getSenderFuture(); + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoImpl.java new file mode 100644 index 0000000000..3b3508c0ab --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojoImpl.java @@ -0,0 +1,48 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.*; +import se.scalablesolutions.akka.dispatch.CompletableFuture; + +public class SimpleJavaPojoImpl extends TypedActor implements SimpleJavaPojo { + + public static boolean _pre = false; + public static boolean _post = false; + public static boolean _down = false; + public static void reset() { + _pre = false; + _post = false; + _down = false; + } + + private String name; + + public Object getSender() { + return getContext().getSender(); + } + + public CompletableFuture getSenderFuture() { + return getContext().getSenderFuture(); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public void preRestart(Throwable e) { + _pre = true; + } + + @Override + public void postRestart(Throwable e) { + _post = true; + } + + public void throwException() { + throw new RuntimeException(); + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/TestUntypedActor.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TestUntypedActor.java new file mode 100644 index 0000000000..7a1d2982e9 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TestUntypedActor.java @@ -0,0 +1,9 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.*; + +public class TestUntypedActor extends UntypedActor { + public void onReceive(Object message, ActorContext context) { + System.out.println("TestUntypedActor got " + message); + } +} \ No newline at end of file diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalTypedActor.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalTypedActor.java new file mode 100644 index 0000000000..6e7c43745b --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalTypedActor.java @@ -0,0 +1,14 @@ +package se.scalablesolutions.akka.actor; + +public interface TransactionalTypedActor { + public String getMapState(String key); + public String getVectorState(); + public String getRefState(); + public void setMapState(String key, String msg); + public void setVectorState(String msg); + public void setRefState(String msg); + public void success(String key, String msg); + public void success(String key, String msg, NestedTransactionalTypedActor nested); + public String failure(String key, String msg, TypedActorFailer failer); + public String failure(String key, String msg, NestedTransactionalTypedActor nested, TypedActorFailer failer); +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalActiveObject.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalTypedActorImpl.java similarity index 69% rename from akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalActiveObject.java rename to akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalTypedActorImpl.java index 515f4fafee..ddaf2fb47d 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalActiveObject.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalTypedActorImpl.java @@ -1,20 +1,16 @@ package se.scalablesolutions.akka.actor; -import se.scalablesolutions.akka.actor.annotation.transactionrequired; -import se.scalablesolutions.akka.actor.annotation.prerestart; -import se.scalablesolutions.akka.actor.annotation.postrestart; -import se.scalablesolutions.akka.actor.annotation.inittransactionalstate; +import se.scalablesolutions.akka.actor.*; import se.scalablesolutions.akka.stm.*; -@transactionrequired -public class TransactionalActiveObject { +public class TransactionalTypedActorImpl extends TypedTransactor implements TransactionalTypedActor { private TransactionalMap mapState; private TransactionalVector vectorState; private Ref refState; private boolean isInitialized = false; - - @inittransactionalstate - public void init() { + + @Override + public void initTransactionalState() { if (!isInitialized) { mapState = new TransactionalMap(); vectorState = new TransactionalVector(); @@ -53,14 +49,14 @@ public class TransactionalActiveObject { refState.swap(msg); } - public void success(String key, String msg, NestedTransactionalActiveObject nested) { + public void success(String key, String msg, NestedTransactionalTypedActor nested) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); nested.success(key, msg); } - public String failure(String key, String msg, ActiveObjectFailer failer) { + public String failure(String key, String msg, TypedActorFailer failer) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); @@ -68,7 +64,7 @@ public class TransactionalActiveObject { return msg; } - public String failure(String key, String msg, NestedTransactionalActiveObject nested, ActiveObjectFailer failer) { + public String failure(String key, String msg, NestedTransactionalTypedActor nested, TypedActorFailer failer) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); @@ -76,17 +72,13 @@ public class TransactionalActiveObject { return msg; } - public void thisMethodHangs(String key, String msg, ActiveObjectFailer failer) { - setMapState(key, msg); - } - - @prerestart - public void preRestart() { + @Override + public void preRestart(Throwable e) { System.out.println("################ PRE RESTART"); } - @postrestart - public void postRestart() { + @Override + public void postRestart(Throwable e) { System.out.println("################ POST RESTART"); } } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/TypedActorFailer.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TypedActorFailer.java new file mode 100644 index 0000000000..b4a69e1cd1 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TypedActorFailer.java @@ -0,0 +1,5 @@ +package se.scalablesolutions.akka.actor; + +public interface TypedActorFailer extends java.io.Serializable { + public int fail(); +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/TypedActorFailerImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TypedActorFailerImpl.java new file mode 100644 index 0000000000..0d01fd801c --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TypedActorFailerImpl.java @@ -0,0 +1,9 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.*; + +public class TypedActorFailerImpl extends TypedActor implements TypedActorFailer { + public int fail() { + throw new RuntimeException("expected"); + } +} diff --git a/akka-core/src/test/resources/META-INF/aop.xml b/akka-core/src/test/resources/META-INF/aop.xml index 2f8d5159a8..bdc167ca54 100644 --- a/akka-core/src/test/resources/META-INF/aop.xml +++ b/akka-core/src/test/resources/META-INF/aop.xml @@ -1,7 +1,7 @@ - + diff --git a/akka-core/src/test/scala/actor/ActiveObjectLifecycleSpec.scala b/akka-core/src/test/scala/actor/ActiveObjectLifecycleSpec.scala deleted file mode 100644 index 2b8e4d502f..0000000000 --- a/akka-core/src/test/scala/actor/ActiveObjectLifecycleSpec.scala +++ /dev/null @@ -1,167 +0,0 @@ -package se.scalablesolutions.akka.actor - -import org.junit.runner.RunWith -import org.scalatest.{BeforeAndAfterAll, Spec} -import org.scalatest.junit.JUnitRunner -import org.scalatest.matchers.ShouldMatchers - -import se.scalablesolutions.akka.actor.ActiveObject._ - -import se.scalablesolutions.akka.config.{OneForOneStrategy, ActiveObjectConfigurator} -import se.scalablesolutions.akka.config.JavaConfig._ - -/** - * @author Martin Krasser - */ -@RunWith(classOf[JUnitRunner]) -class ActiveObjectLifecycleSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { - var conf1: ActiveObjectConfigurator = _ - var conf2: ActiveObjectConfigurator = _ - var conf3: ActiveObjectConfigurator = _ - var conf4: ActiveObjectConfigurator = _ - - override protected def beforeAll() = { - val strategy = new RestartStrategy(new AllForOne(), 3, 1000, Array(classOf[Exception])) - val comp1 = new Component(classOf[SamplePojoAnnotated], new LifeCycle(new Permanent()), 1000) - val comp2 = new Component(classOf[SamplePojoAnnotated], new LifeCycle(new Temporary()), 1000) - val comp3 = new Component(classOf[SamplePojo], new LifeCycle(new Permanent(), new RestartCallbacks("pre", "post")), 1000) - val comp4 = new Component(classOf[SamplePojo], new LifeCycle(new Temporary(), new ShutdownCallback("down")), 1000) - conf1 = new ActiveObjectConfigurator().configure(strategy, Array(comp1)).supervise - conf2 = new ActiveObjectConfigurator().configure(strategy, Array(comp2)).supervise - conf3 = new ActiveObjectConfigurator().configure(strategy, Array(comp3)).supervise - conf4 = new ActiveObjectConfigurator().configure(strategy, Array(comp4)).supervise - } - - override protected def afterAll() = { - conf1.stop - conf2.stop - conf3.stop - conf4.stop - } - - describe("ActiveObject lifecycle management") { - it("should restart supervised, annotated active object on failure") { - val obj = conf1.getInstance[SamplePojoAnnotated](classOf[SamplePojoAnnotated]) - val cdl = obj.newCountdownLatch(2) - assert(AspectInitRegistry.initFor(obj) ne null) - try { - obj.fail - fail("expected exception not thrown") - } catch { - case e: RuntimeException => { - cdl.await - assert(obj._pre) - assert(obj._post) - assert(!obj._down) - assert(AspectInitRegistry.initFor(obj) ne null) - } - } - } - - it("should shutdown supervised, annotated active object on failure") { - val obj = conf2.getInstance[SamplePojoAnnotated](classOf[SamplePojoAnnotated]) - val cdl = obj.newCountdownLatch(1) - assert(AspectInitRegistry.initFor(obj) ne null) - try { - obj.fail - fail("expected exception not thrown") - } catch { - case e: RuntimeException => { - cdl.await - assert(!obj._pre) - assert(!obj._post) - assert(obj._down) - assert(AspectInitRegistry.initFor(obj) eq null) - } - } - } - - it("should restart supervised, non-annotated active object on failure") { - val obj = conf3.getInstance[SamplePojo](classOf[SamplePojo]) - val cdl = obj.newCountdownLatch(2) - assert(AspectInitRegistry.initFor(obj) ne null) - try { - obj.fail - fail("expected exception not thrown") - } catch { - case e: RuntimeException => { - cdl.await - assert(obj._pre) - assert(obj._post) - assert(!obj._down) - assert(AspectInitRegistry.initFor(obj) ne null) - } - } - } - - it("should shutdown supervised, non-annotated active object on failure") { - val obj = conf4.getInstance[SamplePojo](classOf[SamplePojo]) - val cdl = obj.newCountdownLatch(1) - assert(AspectInitRegistry.initFor(obj) ne null) - try { - obj.fail - fail("expected exception not thrown") - } catch { - case e: RuntimeException => { - cdl.await - assert(!obj._pre) - assert(!obj._post) - assert(obj._down) - assert(AspectInitRegistry.initFor(obj) eq null) - } - } - } - - it("should shutdown non-supervised, annotated active object on ActiveObject.stop") { - val obj = ActiveObject.newInstance(classOf[SamplePojoAnnotated]) - assert(AspectInitRegistry.initFor(obj) ne null) - assert("hello akka" === obj.greet("akka")) - ActiveObject.stop(obj) - assert(AspectInitRegistry.initFor(obj) eq null) - assert(!obj._pre) - assert(!obj._post) - assert(obj._down) - try { - obj.greet("akka") - fail("access to stopped active object") - } catch { - case e: Exception => { /* test passed */ } - } - } - - it("should shutdown non-supervised, annotated active object on ActorRegistry.shutdownAll") { - val obj = ActiveObject.newInstance(classOf[SamplePojoAnnotated]) - assert(AspectInitRegistry.initFor(obj) ne null) - assert("hello akka" === obj.greet("akka")) - ActorRegistry.shutdownAll - assert(AspectInitRegistry.initFor(obj) eq null) - assert(!obj._pre) - assert(!obj._post) - assert(obj._down) - try { - obj.greet("akka") - fail("access to stopped active object") - } catch { - case e: Exception => { /* test passed */ } - } - } - - it("should shutdown non-supervised, non-initialized active object on ActiveObject.stop") { - val obj = ActiveObject.newInstance(classOf[SamplePojoAnnotated]) - ActiveObject.stop(obj) - assert(!obj._pre) - assert(!obj._post) - assert(obj._down) - } - - it("both preRestart and postRestart methods should be invoked when an actor is restarted") { - val pojo = ActiveObject.newInstance(classOf[SimpleJavaPojo]) - val supervisor = ActiveObject.newInstance(classOf[SimpleJavaPojo]) - link(supervisor,pojo, new OneForOneStrategy(3, 2000),Array(classOf[Throwable])) - pojo.throwException - Thread.sleep(500) - pojo.pre should be(true) - pojo.post should be(true) - } - } -} \ No newline at end of file diff --git a/akka-core/src/test/scala/actor/NestedTransactionalActiveObjectSpec.scala b/akka-core/src/test/scala/actor/NestedTransactionalTypedActorSpec.scala similarity index 67% rename from akka-core/src/test/scala/actor/NestedTransactionalActiveObjectSpec.scala rename to akka-core/src/test/scala/actor/NestedTransactionalTypedActorSpec.scala index afb9f9523e..e0c59800bc 100644 --- a/akka-core/src/test/scala/actor/NestedTransactionalActiveObjectSpec.scala +++ b/akka-core/src/test/scala/actor/NestedTransactionalTypedActorSpec.scala @@ -1,4 +1,4 @@ -/** + /** * Copyright (C) 2009-2010 Scalable Solutions AB */ @@ -14,7 +14,7 @@ import org.junit.runner.RunWith import se.scalablesolutions.akka.actor._ @RunWith(classOf[JUnitRunner]) -class NestedTransactionalActiveObjectSpec extends +class NestedTransactionalTypedActorSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { @@ -25,14 +25,12 @@ class NestedTransactionalActiveObjectSpec extends // ActorRegistry.shutdownAll } - describe("Declaratively nested supervised transactional in-memory Active Object") { + describe("Declaratively nested supervised transactional in-memory TypedActor") { it("map should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state - val nested = ActiveObject.newInstance(classOf[NestedTransactionalActiveObject]) - nested.init + val nested = TypedActor.newInstance(classOf[NestedTransactionalTypedActor], classOf[NestedTransactionalTypedActorImpl]) nested.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state", nested) // transactionrequired stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") @@ -40,13 +38,11 @@ class NestedTransactionalActiveObjectSpec extends } it("map should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state - val nested = ActiveObject.newInstance(classOf[NestedTransactionalActiveObject]) - nested.init + val nested = TypedActor.newInstance(classOf[NestedTransactionalTypedActor], classOf[NestedTransactionalTypedActorImpl]) nested.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state - val failer = ActiveObject.newInstance(classOf[ActiveObjectFailer]) + val failer = TypedActor.newInstance(classOf[TypedActorFailer], classOf[TypedActorFailerImpl]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) fail("should have thrown an exception") @@ -56,11 +52,9 @@ class NestedTransactionalActiveObjectSpec extends } it("vector should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setVectorState("init") // set init state - val nested = ActiveObject.newInstance(classOf[NestedTransactionalActiveObject]) - nested.init + val nested = TypedActor.newInstance(classOf[NestedTransactionalTypedActor], classOf[NestedTransactionalTypedActorImpl]) nested.setVectorState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state", nested) // transactionrequired stateful.getVectorState should equal("new state") @@ -68,13 +62,11 @@ class NestedTransactionalActiveObjectSpec extends } it("vector should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setVectorState("init") // set init state - val nested = ActiveObject.newInstance(classOf[NestedTransactionalActiveObject]) - nested.init + val nested = TypedActor.newInstance(classOf[NestedTransactionalTypedActor], classOf[NestedTransactionalTypedActorImpl]) nested.setVectorState("init") // set init state - val failer = ActiveObject.newInstance(classOf[ActiveObjectFailer]) + val failer = TypedActor.newInstance(classOf[TypedActorFailer], classOf[TypedActorFailerImpl]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) fail("should have thrown an exception") @@ -84,10 +76,8 @@ class NestedTransactionalActiveObjectSpec extends } it("ref should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init - val nested = ActiveObject.newInstance(classOf[NestedTransactionalActiveObject]) - nested.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) + val nested = TypedActor.newInstance(classOf[NestedTransactionalTypedActor], classOf[NestedTransactionalTypedActorImpl]) stateful.setRefState("init") // set init state nested.setRefState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state", nested) @@ -96,13 +86,11 @@ class NestedTransactionalActiveObjectSpec extends } it("ref should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init - val nested = ActiveObject.newInstance(classOf[NestedTransactionalActiveObject]) - nested.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) + val nested = TypedActor.newInstance(classOf[NestedTransactionalTypedActor], classOf[NestedTransactionalTypedActorImpl]) stateful.setRefState("init") // set init state nested.setRefState("init") // set init state - val failer = ActiveObject.newInstance(classOf[ActiveObjectFailer]) + val failer = TypedActor.newInstance(classOf[TypedActorFailer], classOf[TypedActorFailerImpl]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) fail("should have thrown an exception") diff --git a/akka-core/src/test/scala/remote/RemoteTransactionalActiveObjectSpec.scala b/akka-core/src/test/scala/actor/RemoteTransactionalTypedActorSpec.scala similarity index 67% rename from akka-core/src/test/scala/remote/RemoteTransactionalActiveObjectSpec.scala rename to akka-core/src/test/scala/actor/RemoteTransactionalTypedActorSpec.scala index 21fadb14ac..71d44fd4bd 100644 --- a/akka-core/src/test/scala/remote/RemoteTransactionalActiveObjectSpec.scala +++ b/akka-core/src/test/scala/actor/RemoteTransactionalTypedActorSpec.scala @@ -2,33 +2,36 @@ * Copyright (C) 2009-2010 Scalable Solutions AB */ -package se.scalablesolutions.akka.actor.remote +package se.scalablesolutions.akka.actor import org.scalatest.Spec +import org.scalatest.Assertions import org.scalatest.matchers.ShouldMatchers import org.scalatest.BeforeAndAfterAll import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith -import se.scalablesolutions.akka.config.Config -import se.scalablesolutions.akka.config.ActiveObjectConfigurator -import se.scalablesolutions.akka.remote.{RemoteServer, RemoteClient} +import org.junit.{Test, Before, After} -object RemoteTransactionalActiveObjectSpec { +import se.scalablesolutions.akka.config.Config +import se.scalablesolutions.akka.config.TypedActorConfigurator +import se.scalablesolutions.akka.remote.{RemoteNode, RemoteServer, RemoteClient} + +object RemoteTransactionalTypedActorSpec { val HOSTNAME = "localhost" val PORT = 9988 var server: RemoteServer = null } @RunWith(classOf[JUnitRunner]) -class RemoteTransactionalActiveObjectSpec extends +class RemoteTransactionalTypedActorSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { - import RemoteTransactionalActiveObjectSpec._ + import RemoteTransactionalTypedActorSpec._ Config.config - private val conf = new ActiveObjectConfigurator + private val conf = new TypedActorConfigurator private var messageLog = "" override def beforeAll = { @@ -48,19 +51,19 @@ class RemoteTransactionalActiveObjectSpec extends } } - describe("Remote transactional in-memory Active Object ") { + describe("Remote transactional in-memory TypedActor ") { /* it("map should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) + val stateful = TypedActor.newRemoteInstance(classOf[TransactionalTypedActor], 1000, HOSTNAME, PORT) stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") } it("map should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) + val stateful = TypedActor.newRemoteInstance(classOf[TransactionalTypedActor], 1000, HOSTNAME, PORT) stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state - val failer =ActiveObject.newRemoteInstance(classOf[ActiveObjectFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[ActiveObjectFailer]) + val failer =TypedActor.newRemoteInstance(classOf[TypedActorFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method fail("should have thrown an exception") @@ -69,16 +72,16 @@ class RemoteTransactionalActiveObjectSpec extends } it("vector should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) + val stateful = TypedActor.newRemoteInstance(classOf[TransactionalTypedActor], 1000, HOSTNAME, PORT) stateful.setVectorState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired stateful.getVectorState should equal("new state") } it("vector should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) + val stateful = TypedActor.newRemoteInstance(classOf[TransactionalTypedActor], 1000, HOSTNAME, PORT) stateful.setVectorState("init") // set init state - val failer =ActiveObject.newRemoteInstance(classOf[ActiveObjectFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[ActiveObjectFailer]) + val failer =TypedActor.newRemoteInstance(classOf[TypedActorFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method fail("should have thrown an exception") @@ -87,16 +90,16 @@ class RemoteTransactionalActiveObjectSpec extends } it("ref should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) + val stateful = TypedActor.newRemoteInstance(classOf[TransactionalTypedActor], 1000, HOSTNAME, PORT) stateful.setRefState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired stateful.getRefState should equal("new state") } it("ref should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) + val stateful = TypedActor.newRemoteInstance(classOf[TransactionalTypedActor], 1000, HOSTNAME, PORT) stateful.setRefState("init") // set init state - val failer =ActiveObject.newRemoteInstance(classOf[ActiveObjectFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[ActiveObjectFailer]) + val failer =TypedActor.newRemoteInstance(classOf[TypedActorFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method fail("should have thrown an exception") diff --git a/akka-core/src/test/scala/actor/RestartNestedTransactionalActiveObjectSpec.scala b/akka-core/src/test/scala/actor/RestartNestedTransactionalTypedActorSpec.scala similarity index 75% rename from akka-core/src/test/scala/actor/RestartNestedTransactionalActiveObjectSpec.scala rename to akka-core/src/test/scala/actor/RestartNestedTransactionalTypedActorSpec.scala index 67076aff7c..d853230371 100644 --- a/akka-core/src/test/scala/actor/RestartNestedTransactionalActiveObjectSpec.scala +++ b/akka-core/src/test/scala/actor/RestartNestedTransactionalTypedActorSpec.scala @@ -13,53 +13,57 @@ import org.junit.runner.RunWith import se.scalablesolutions.akka.config.Config import se.scalablesolutions.akka.config._ -import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.TypedActorConfigurator import se.scalablesolutions.akka.config.JavaConfig._ import se.scalablesolutions.akka.actor._ @RunWith(classOf[JUnitRunner]) -class RestartNestedTransactionalActiveObjectSpec extends +class RestartNestedTransactionalTypedActorSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { - private val conf = new ActiveObjectConfigurator + private val conf = new TypedActorConfigurator private var messageLog = "" override def beforeAll { + /* Config.config conf.configure( new RestartStrategy(new AllForOne, 3, 5000, List(classOf[Exception]).toArray), List( - new Component(classOf[TransactionalActiveObject], + new Component(classOf[TransactionalTypedActor], new LifeCycle(new Permanent), 10000), - new Component(classOf[NestedTransactionalActiveObject], + new Component(classOf[NestedTransactionalTypedActor], new LifeCycle(new Permanent), 10000), - new Component(classOf[ActiveObjectFailer], + new Component(classOf[TypedActorFailer], new LifeCycle(new Permanent), 10000) ).toArray).supervise + */ } override def afterAll { + /* conf.stop ActorRegistry.shutdownAll + */ } describe("Restart nested supervised transactional Active Object") { /* it("map should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[TransactionalActiveObject]) + val stateful = conf.getInstance(classOf[TransactionalTypedActor]) stateful.init stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state - val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) + val nested = conf.getInstance(classOf[NestedTransactionalTypedActor]) nested.init nested.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state - val failer = conf.getInstance(classOf[ActiveObjectFailer]) + val failer = conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) @@ -71,15 +75,15 @@ class RestartNestedTransactionalActiveObjectSpec extends } it("vector should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[TransactionalActiveObject]) + val stateful = conf.getInstance(classOf[TransactionalTypedActor]) stateful.init stateful.setVectorState("init") // set init state - val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) + val nested = conf.getInstance(classOf[NestedTransactionalTypedActor]) nested.init nested.setVectorState("init") // set init state - val failer = conf.getInstance(classOf[ActiveObjectFailer]) + val failer = conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) @@ -91,15 +95,15 @@ class RestartNestedTransactionalActiveObjectSpec extends } it("ref should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[TransactionalActiveObject]) + val stateful = conf.getInstance(classOf[TransactionalTypedActor]) stateful.init - val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) + val nested = conf.getInstance(classOf[NestedTransactionalTypedActor]) nested.init stateful.setRefState("init") // set init state nested.setRefState("init") // set init state - val failer = conf.getInstance(classOf[ActiveObjectFailer]) + val failer = conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) diff --git a/akka-core/src/test/scala/actor/RestartTransactionalActiveObjectSpec.scala b/akka-core/src/test/scala/actor/RestartTransactionalTypedActorSpec.scala similarity index 78% rename from akka-core/src/test/scala/actor/RestartTransactionalActiveObjectSpec.scala rename to akka-core/src/test/scala/actor/RestartTransactionalTypedActorSpec.scala index a1a2f8b507..a4f9c61f59 100644 --- a/akka-core/src/test/scala/actor/RestartTransactionalActiveObjectSpec.scala +++ b/akka-core/src/test/scala/actor/RestartTransactionalTypedActorSpec.scala @@ -13,17 +13,17 @@ import org.junit.runner.RunWith import se.scalablesolutions.akka.config.Config import se.scalablesolutions.akka.config._ -import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.TypedActorConfigurator import se.scalablesolutions.akka.config.JavaConfig._ import se.scalablesolutions.akka.actor._ @RunWith(classOf[JUnitRunner]) -class RestartTransactionalActiveObjectSpec extends +class RestartTransactionalTypedActorSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { - private val conf = new ActiveObjectConfigurator + private val conf = new TypedActorConfigurator private var messageLog = "" def before { @@ -32,11 +32,11 @@ class RestartTransactionalActiveObjectSpec extends new RestartStrategy(new AllForOne, 3, 5000, List(classOf[Exception]).toArray), List( new Component( - classOf[TransactionalActiveObject], + classOf[TransactionalTypedActor], new LifeCycle(new Temporary), 10000), new Component( - classOf[ActiveObjectFailer], + classOf[TypedActorFailer], new LifeCycle(new Temporary), 10000) ).toArray).supervise @@ -51,10 +51,10 @@ class RestartTransactionalActiveObjectSpec extends /* it("map should rollback state for stateful server in case of failure") { before - val stateful = conf.getInstance(classOf[TransactionalActiveObject]) + val stateful = conf.getInstance(classOf[TransactionalTypedActor]) stateful.init stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") - val failer = conf.getInstance(classOf[ActiveObjectFailer]) + val failer = conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") @@ -65,10 +65,10 @@ class RestartTransactionalActiveObjectSpec extends it("vector should rollback state for stateful server in case of failure") { before - val stateful = conf.getInstance(classOf[TransactionalActiveObject]) + val stateful = conf.getInstance(classOf[TransactionalTypedActor]) stateful.init stateful.setVectorState("init") // set init state - val failer = conf.getInstance(classOf[ActiveObjectFailer]) + val failer = conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") @@ -78,10 +78,10 @@ class RestartTransactionalActiveObjectSpec extends } it("ref should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[TransactionalActiveObject]) + val stateful = conf.getInstance(classOf[TransactionalTypedActor]) stateful.init stateful.setRefState("init") // set init state - val failer = conf.getInstance(classOf[ActiveObjectFailer]) + val failer = conf.getInstance(classOf[TypedActorFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") diff --git a/akka-core/src/test/scala/actor/TransactionalActiveObjectSpec.scala b/akka-core/src/test/scala/actor/TransactionalTypedActorSpec.scala similarity index 73% rename from akka-core/src/test/scala/actor/TransactionalActiveObjectSpec.scala rename to akka-core/src/test/scala/actor/TransactionalTypedActorSpec.scala index 1225df9a92..e8ac4c3fd7 100644 --- a/akka-core/src/test/scala/actor/TransactionalActiveObjectSpec.scala +++ b/akka-core/src/test/scala/actor/TransactionalTypedActorSpec.scala @@ -14,7 +14,7 @@ import org.junit.runner.RunWith import se.scalablesolutions.akka.actor._ @RunWith(classOf[JUnitRunner]) -class TransactionalActiveObjectSpec extends +class TransactionalTypedActorSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { @@ -27,18 +27,16 @@ class TransactionalActiveObjectSpec extends describe("Declaratively supervised transactional in-memory Active Object ") { it("map should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") } it("map should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") - val failer = ActiveObject.newInstance(classOf[ActiveObjectFailer]) + val failer = TypedActor.newInstance(classOf[TypedActorFailer], classOf[TypedActorFailerImpl]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") @@ -47,18 +45,16 @@ class TransactionalActiveObjectSpec extends } it("vector should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setVectorState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") stateful.getVectorState should equal("new state") } it("vector should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setVectorState("init") // set init state - val failer = ActiveObject.newInstance(classOf[ActiveObjectFailer]) + val failer = TypedActor.newInstance(classOf[TypedActorFailer], classOf[TypedActorFailerImpl]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") @@ -67,18 +63,16 @@ class TransactionalActiveObjectSpec extends } it("ref should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setRefState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") stateful.getRefState should equal("new state") } it("ref should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newInstance(classOf[TransactionalActiveObject]) - stateful.init + val stateful = TypedActor.newInstance(classOf[TransactionalTypedActor], classOf[TransactionalTypedActorImpl]) stateful.setRefState("init") // set init state - val failer = ActiveObject.newInstance(classOf[ActiveObjectFailer]) + val failer = TypedActor.newInstance(classOf[TypedActorFailer], classOf[TypedActorFailerImpl]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") diff --git a/akka-core/src/test/scala/actor/ActiveObjectContextSpec.scala b/akka-core/src/test/scala/actor/TypedActorContextSpec.scala similarity index 58% rename from akka-core/src/test/scala/actor/ActiveObjectContextSpec.scala rename to akka-core/src/test/scala/actor/TypedActorContextSpec.scala index 62b9962ac2..5c3fb629ad 100644 --- a/akka-core/src/test/scala/actor/ActiveObjectContextSpec.scala +++ b/akka-core/src/test/scala/actor/TypedActorContextSpec.scala @@ -5,6 +5,7 @@ package se.scalablesolutions.akka.actor import org.scalatest.Spec +import org.scalatest.Assertions import org.scalatest.matchers.ShouldMatchers import org.scalatest.BeforeAndAfterAll import org.scalatest.junit.JUnitRunner @@ -13,15 +14,15 @@ import org.junit.runner.RunWith import se.scalablesolutions.akka.dispatch.DefaultCompletableFuture; @RunWith(classOf[JUnitRunner]) -class ActiveObjectContextSpec extends +class TypedActorContextSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { - describe("ActiveObjectContext") { - it("context.sender should return the sender Active Object reference") { - val pojo = ActiveObject.newInstance(classOf[SimpleJavaPojo]) - val pojoCaller = ActiveObject.newInstance(classOf[SimpleJavaPojoCaller]) + describe("TypedActorContext") { + it("context.sender should return the sender TypedActor reference") { + val pojo = TypedActor.newInstance(classOf[SimpleJavaPojo], classOf[SimpleJavaPojoImpl]) + val pojoCaller = TypedActor.newInstance(classOf[SimpleJavaPojoCaller], classOf[SimpleJavaPojoCallerImpl]) pojoCaller.setPojo(pojo) try { pojoCaller.getSenderFromSimpleJavaPojo should equal (pojoCaller) @@ -30,9 +31,9 @@ class ActiveObjectContextSpec extends } } - it("context.senderFuture should return the senderFuture Active Object reference") { - val pojo = ActiveObject.newInstance(classOf[SimpleJavaPojo]) - val pojoCaller = ActiveObject.newInstance(classOf[SimpleJavaPojoCaller]) + it("context.senderFuture should return the senderFuture TypedActor reference") { + val pojo = TypedActor.newInstance(classOf[SimpleJavaPojo], classOf[SimpleJavaPojoImpl]) + val pojoCaller = TypedActor.newInstance(classOf[SimpleJavaPojoCaller], classOf[SimpleJavaPojoCallerImpl]) pojoCaller.setPojo(pojo) try { pojoCaller.getSenderFutureFromSimpleJavaPojo.getClass.getName should equal (classOf[DefaultCompletableFuture[_]].getName) diff --git a/akka-core/src/test/scala/actor/ActiveObjectGuiceConfiguratorSpec.scala b/akka-core/src/test/scala/actor/TypedActorGuiceConfiguratorSpec.scala similarity index 87% rename from akka-core/src/test/scala/actor/ActiveObjectGuiceConfiguratorSpec.scala rename to akka-core/src/test/scala/actor/TypedActorGuiceConfiguratorSpec.scala index 178d16f8d4..d076ec52cf 100644 --- a/akka-core/src/test/scala/actor/ActiveObjectGuiceConfiguratorSpec.scala +++ b/akka-core/src/test/scala/actor/TypedActorGuiceConfiguratorSpec.scala @@ -8,23 +8,25 @@ import com.google.inject.AbstractModule import com.google.inject.Scopes import org.scalatest.Spec +import org.scalatest.Assertions import org.scalatest.matchers.ShouldMatchers import org.scalatest.BeforeAndAfterAll import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import se.scalablesolutions.akka.config.Config -import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.TypedActorConfigurator import se.scalablesolutions.akka.config.JavaConfig._ import se.scalablesolutions.akka.dispatch._ +import se.scalablesolutions.akka.dispatch.FutureTimeoutException @RunWith(classOf[JUnitRunner]) -class ActiveObjectGuiceConfiguratorSpec extends +class TypedActorGuiceConfiguratorSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { - private val conf = new ActiveObjectConfigurator + private val conf = new TypedActorConfigurator private var messageLog = "" override def beforeAll { @@ -38,6 +40,7 @@ class ActiveObjectGuiceConfiguratorSpec extends List( new Component( classOf[Foo], + classOf[FooImpl], new LifeCycle(new Permanent), 1000, dispatcher), @@ -53,9 +56,9 @@ class ActiveObjectGuiceConfiguratorSpec extends override def afterAll = conf.stop - describe("ActiveObjectGuiceConfigurator") { + describe("TypedActorGuiceConfigurator") { /* - it("should inject active object using guice") { + it("should inject typed actor using guice") { messageLog = "" val foo = conf.getInstance(classOf[Foo]) val bar = conf.getInstance(classOf[Bar]) @@ -79,7 +82,7 @@ class ActiveObjectGuiceConfiguratorSpec extends } } - it("should be able to invoke active object") { + it("should be able to invoke typed actor") { messageLog = "" val foo = conf.getInstance(classOf[Foo]) messageLog += foo.foo("foo ") @@ -89,7 +92,7 @@ class ActiveObjectGuiceConfiguratorSpec extends messageLog should equal("foo return_foo before_bar ") } - it("should be able to invoke active object's invocation") { + it("should be able to invoke typed actor's invocation") { messageLog = "" val foo = conf.getInstance(classOf[Foo]) val bar = conf.getInstance(classOf[Bar]) diff --git a/akka-core/src/test/scala/actor/TypedActorLifecycleSpec.scala b/akka-core/src/test/scala/actor/TypedActorLifecycleSpec.scala new file mode 100644 index 0000000000..02a5712410 --- /dev/null +++ b/akka-core/src/test/scala/actor/TypedActorLifecycleSpec.scala @@ -0,0 +1,169 @@ +package se.scalablesolutions.akka.actor + +import org.junit.runner.RunWith +import org.scalatest.{BeforeAndAfterAll, Spec} +import org.scalatest.junit.JUnitRunner +import org.scalatest.matchers.ShouldMatchers + +import se.scalablesolutions.akka.actor.TypedActor._ + +import se.scalablesolutions.akka.config.{OneForOneStrategy, TypedActorConfigurator} +import se.scalablesolutions.akka.config.JavaConfig._ + +import java.util.concurrent.CountDownLatch + +/** + * @author Martin Krasser + */ +@RunWith(classOf[JUnitRunner]) +class TypedActorLifecycleSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { + var conf1: TypedActorConfigurator = _ + var conf2: TypedActorConfigurator = _ + + override protected def beforeAll() = { + val strategy = new RestartStrategy(new AllForOne(), 3, 1000, Array(classOf[Exception])) + val comp3 = new Component(classOf[SamplePojo], classOf[SamplePojoImpl], new LifeCycle(new Permanent()), 1000) + val comp4 = new Component(classOf[SamplePojo], classOf[SamplePojoImpl], new LifeCycle(new Temporary()), 1000) + conf1 = new TypedActorConfigurator().configure(strategy, Array(comp3)).supervise + conf2 = new TypedActorConfigurator().configure(strategy, Array(comp4)).supervise + } + + override protected def afterAll() = { + conf1.stop + conf2.stop + } + + describe("TypedActor lifecycle management") { + it("should restart supervised, non-annotated typed actor on failure") { + SamplePojoImpl.reset + val obj = conf1.getInstance[SamplePojo](classOf[SamplePojo]) + val cdl = new CountDownLatch(2) + SamplePojoImpl.latch = cdl + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(SamplePojoImpl._pre) + assert(SamplePojoImpl._post) + assert(!SamplePojoImpl._down) + assert(AspectInitRegistry.initFor(obj) ne null) + } + } + } + + it("should shutdown supervised, non-annotated typed actor on failure") { + SamplePojoImpl.reset + val obj = conf2.getInstance[SamplePojo](classOf[SamplePojo]) + val cdl = new CountDownLatch(1) + SamplePojoImpl.latch = cdl + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(!SamplePojoImpl._pre) + assert(!SamplePojoImpl._post) + assert(SamplePojoImpl._down) + assert(AspectInitRegistry.initFor(obj) eq null) + } + } + } + + it("should shutdown non-supervised, non-initialized typed actor on TypedActor.stop") { + SamplePojoImpl.reset + val obj = TypedActor.newInstance(classOf[SamplePojo], classOf[SamplePojoImpl]) + TypedActor.stop(obj) + assert(!SamplePojoImpl._pre) + assert(!SamplePojoImpl._post) + assert(SamplePojoImpl._down) + } + + it("both preRestart and postRestart methods should be invoked when an actor is restarted") { + SamplePojoImpl.reset + val pojo = TypedActor.newInstance(classOf[SimpleJavaPojo], classOf[SimpleJavaPojoImpl]) + val supervisor = TypedActor.newInstance(classOf[SimpleJavaPojo], classOf[SimpleJavaPojoImpl]) + link(supervisor, pojo, new OneForOneStrategy(3, 2000), Array(classOf[Throwable])) + pojo.throwException + Thread.sleep(500) + SimpleJavaPojoImpl._pre should be(true) + SimpleJavaPojoImpl._post should be(true) + } + + /* + it("should shutdown non-supervised, annotated typed actor on TypedActor.stop") { + val obj = TypedActor.newInstance(classOf[SamplePojoAnnotated]) + assert(AspectInitRegistry.initFor(obj) ne null) + assert("hello akka" === obj.greet("akka")) + TypedActor.stop(obj) + assert(AspectInitRegistry.initFor(obj) eq null) + assert(!obj.pre) + assert(!obj.post) + assert(obj.down) + try { + obj.greet("akka") + fail("access to stopped typed actor") + } catch { + case e: Exception => {} + } + } + + it("should shutdown non-supervised, annotated typed actor on ActorRegistry.shutdownAll") { + val obj = TypedActor.newInstance(classOf[SamplePojoAnnotated]) + assert(AspectInitRegistry.initFor(obj) ne null) + assert("hello akka" === obj.greet("akka")) + ActorRegistry.shutdownAll + assert(AspectInitRegistry.initFor(obj) eq null) + assert(!obj.pre) + assert(!obj.post) + assert(obj.down) + try { + obj.greet("akka") + fail("access to stopped typed actor") + } catch { + case e: Exception => { } + } + } + + it("should restart supervised, annotated typed actor on failure") { + val obj = conf1.getInstance[SamplePojoAnnotated](classOf[SamplePojoAnnotated]) + val cdl = obj.newCountdownLatch(2) + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(obj.pre) + assert(obj.post) + assert(!obj.down) + assert(AspectInitRegistry.initFor(obj) ne null) + } + } + } + + it("should shutdown supervised, annotated typed actor on failure") { + val obj = conf2.getInstance[SamplePojoAnnotated](classOf[SamplePojoAnnotated]) + val cdl = obj.newCountdownLatch(1) + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(!obj.pre) + assert(!obj.post) + assert(obj.down) + assert(AspectInitRegistry.initFor(obj) eq null) + } + } + } + */ + } +} \ No newline at end of file diff --git a/akka-core/src/test/scala/actor/ActorObjectUtilFunctionsSpec.scala b/akka-core/src/test/scala/actor/TypedActorUtilFunctionsSpec.scala similarity index 93% rename from akka-core/src/test/scala/actor/ActorObjectUtilFunctionsSpec.scala rename to akka-core/src/test/scala/actor/TypedActorUtilFunctionsSpec.scala index 3c540f02ab..48424f3c17 100644 --- a/akka-core/src/test/scala/actor/ActorObjectUtilFunctionsSpec.scala +++ b/akka-core/src/test/scala/actor/TypedActorUtilFunctionsSpec.scala @@ -4,7 +4,7 @@ import org.scalatest.Suite import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner import org.scalatest.matchers.MustMatchers -import org.junit.Test +import org.junit.{Before, After, Test} import java.util.concurrent.{ CountDownLatch, TimeUnit } @RunWith(classOf[JUnitRunner]) diff --git a/akka-samples/akka-sample-camel/src/main/java/sample/camel/BeanImpl.java b/akka-samples/akka-sample-camel/src/main/java/sample/camel/BeanImpl.java index 10437e7624..5fa9e8c599 100644 --- a/akka-samples/akka-sample-camel/src/main/java/sample/camel/BeanImpl.java +++ b/akka-samples/akka-sample-camel/src/main/java/sample/camel/BeanImpl.java @@ -1,9 +1,10 @@ package sample.camel; +import se.scalablesolutions.akka.actor.TypedActor; /** * @author Martin Krasser */ -public class BeanImpl implements BeanIntf { +public class BeanImpl extends TypedActor implements BeanIntf { public String foo(String s) { return "hello " + s; diff --git a/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo1.java b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo1.java index ed29ac30e6..d099816161 100644 --- a/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo1.java +++ b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo1.java @@ -8,17 +8,10 @@ import se.scalablesolutions.akka.actor.annotation.consume; /** * @author Martin Krasser */ -public class ConsumerPojo1 { - +public interface ConsumerPojo1 { @consume("file:data/input/pojo") - public void foo(String body) { - System.out.println("Received message:"); - System.out.println(body); - } - + public void foo(String body); + @consume("jetty:http://0.0.0.0:8877/camel/pojo") - public String bar(@Body String body, @Header("name") String header) { - return String.format("body=%s header=%s", body, header); - } - + public String bar(@Body String body, @Header("name") String header); } diff --git a/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo1Impl.java b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo1Impl.java new file mode 100644 index 0000000000..8f3ca9625d --- /dev/null +++ b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo1Impl.java @@ -0,0 +1,24 @@ +package sample.camel; + +import org.apache.camel.Body; +import org.apache.camel.Header; + +import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.TypedActor; + +/** + * @author Martin Krasser + */ +public class ConsumerPojo1Impl extends TypedActor implements ConsumerPojo1 { + + @consume("file:data/input/pojo") + public void foo(String body) { + System.out.println("Received message:"); + System.out.println(body); + } + + @consume("jetty:http://0.0.0.0:8877/camel/pojo") + public String bar(@Body String body, @Header("name") String header) { + return String.format("body=%s header=%s", body, header); + } +} diff --git a/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo2.java b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo2.java index 429e6043ad..c0ef7a6798 100644 --- a/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo2.java +++ b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo2.java @@ -7,11 +7,8 @@ import se.scalablesolutions.akka.actor.annotation.consume; /** * @author Martin Krasser */ -public class ConsumerPojo2 { +public interface ConsumerPojo2 { @consume("direct:default") - public String foo(String body) { - return String.format("default: %s", body); - } - + public String foo(String body); } \ No newline at end of file diff --git a/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo2Impl.java b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo2Impl.java new file mode 100644 index 0000000000..eeca816d1b --- /dev/null +++ b/akka-samples/akka-sample-camel/src/main/java/sample/camel/ConsumerPojo2Impl.java @@ -0,0 +1,18 @@ +package sample.camel; + +import org.apache.camel.Body; +import org.apache.camel.Header; + +import se.scalablesolutions.akka.actor.TypedActor; +import se.scalablesolutions.akka.actor.annotation.consume; + +/** + * @author Martin Krasser + */ +public class ConsumerPojo2Impl extends TypedActor implements ConsumerPojo2 { + + @consume("direct:default") + public String foo(String body) { + return String.format("default: %s", body); + } +} \ No newline at end of file diff --git a/akka-samples/akka-sample-camel/src/main/java/sample/camel/RemoteConsumerPojo1.java b/akka-samples/akka-sample-camel/src/main/java/sample/camel/RemoteConsumerPojo1.java index ab7e878b0d..929a82b65d 100644 --- a/akka-samples/akka-sample-camel/src/main/java/sample/camel/RemoteConsumerPojo1.java +++ b/akka-samples/akka-sample-camel/src/main/java/sample/camel/RemoteConsumerPojo1.java @@ -8,11 +8,8 @@ import se.scalablesolutions.akka.actor.annotation.consume; /** * @author Martin Krasser */ -public class RemoteConsumerPojo1 { +public interface RemoteConsumerPojo1 { @consume("jetty:http://localhost:6644/camel/remote-active-object-1") - public String foo(@Body String body, @Header("name") String header) { - return String.format("remote1: body=%s header=%s", body, header); - } - + public String foo(@Body String body, @Header("name") String header); } diff --git a/akka-samples/akka-sample-camel/src/main/java/sample/camel/RemoteConsumerPojo1Impl.java b/akka-samples/akka-sample-camel/src/main/java/sample/camel/RemoteConsumerPojo1Impl.java new file mode 100644 index 0000000000..858afcdbeb --- /dev/null +++ b/akka-samples/akka-sample-camel/src/main/java/sample/camel/RemoteConsumerPojo1Impl.java @@ -0,0 +1,18 @@ +package sample.camel; + +import org.apache.camel.Body; +import org.apache.camel.Header; + +import se.scalablesolutions.akka.actor.annotation.consume; +import se.scalablesolutions.akka.actor.TypedActor; + +/** + * @author Martin Krasser + */ +public class RemoteConsumerPojo1Impl extends TypedActor implements RemoteConsumerPojo1 { + + @consume("jetty:http://localhost:6644/camel/remote-active-object-1") + public String foo(@Body String body, @Header("name") String header) { + return String.format("remote1: body=%s header=%s", body, header); + } +} diff --git a/akka-samples/akka-sample-camel/src/main/scala/Boot.scala b/akka-samples/akka-sample-camel/src/main/scala/Boot.scala index bcb884d186..3b733fa988 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/Boot.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/Boot.scala @@ -7,7 +7,7 @@ import org.apache.camel.spring.spi.ApplicationContextRegistry import org.springframework.context.support.ClassPathXmlApplicationContext import se.scalablesolutions.akka.actor.Actor._ -import se.scalablesolutions.akka.actor.{ActiveObject, Supervisor} +import se.scalablesolutions.akka.actor.{TypedActor, Supervisor} import se.scalablesolutions.akka.camel.CamelContextManager import se.scalablesolutions.akka.config.ScalaConfig._ @@ -89,7 +89,7 @@ class Boot { // Active object example // ----------------------------------------------------------------------- - ActiveObject.newInstance(classOf[ConsumerPojo1]) + TypedActor.newInstance(classOf[ConsumerPojo1], classOf[ConsumerPojo1Impl]) } /** diff --git a/akka-samples/akka-sample-camel/src/main/scala/ClientApplication.scala b/akka-samples/akka-sample-camel/src/main/scala/ClientApplication.scala index 467d715360..5be24f1c8f 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/ClientApplication.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/ClientApplication.scala @@ -1,7 +1,7 @@ package sample.camel import se.scalablesolutions.akka.actor.Actor._ -import se.scalablesolutions.akka.actor.{ActiveObject, Actor, ActorRef} +import se.scalablesolutions.akka.actor.{TypedActor, Actor, ActorRef} import se.scalablesolutions.akka.camel.Message import se.scalablesolutions.akka.remote.RemoteClient @@ -18,15 +18,15 @@ object ClientApplication { val actor1 = actorOf[RemoteActor1] val actor2 = RemoteClient.actorFor("remote2", "localhost", 7777) - val actobj1 = ActiveObject.newRemoteInstance(classOf[RemoteConsumerPojo1], "localhost", 7777) - //val actobj2 = TODO: create reference to server-managed active object (RemoteConsumerPojo2) + val actobj1 = TypedActor.newRemoteInstance(classOf[RemoteConsumerPojo1], classOf[RemoteConsumerPojo1Impl], "localhost", 7777) + //val actobj2 = TODO: create reference to server-managed typed actor (RemoteConsumerPojo2) actor1.start println(actor1 !! Message("actor1")) // activates and publishes actor remotely println(actor2 !! Message("actor2")) // actor already activated and published remotely - println(actobj1.foo("x", "y")) // activates and publishes active object methods remotely + println(actobj1.foo("x", "y")) // activates and publishes typed actor methods remotely // ... } diff --git a/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala b/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala index 941da479b3..6584651f68 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala @@ -5,7 +5,7 @@ import org.apache.camel.builder.RouteBuilder import org.apache.camel.spring.spi.ApplicationContextRegistry import org.springframework.context.support.ClassPathXmlApplicationContext -import se.scalablesolutions.akka.actor.{Actor, ActorRegistry, ActiveObject} +import se.scalablesolutions.akka.actor.{Actor, ActorRegistry, TypedActor} import se.scalablesolutions.akka.camel._ import se.scalablesolutions.akka.util.Logging @@ -16,10 +16,9 @@ object StandaloneApplication { def main(args: Array[String]) { import CamelContextManager.context - // 'externally' register active objects + // 'externally' register typed actors val registry = new SimpleRegistry - registry.put("pojo1", ActiveObject.newInstance(classOf[BeanIntf], new BeanImpl)) - registry.put("pojo2", ActiveObject.newInstance(classOf[BeanImpl])) + registry.put("pojo1", TypedActor.newInstance(classOf[BeanIntf], classOf[BeanImpl])) // customize CamelContext CamelContextManager.init(new DefaultCamelContext(registry)) @@ -28,12 +27,12 @@ object StandaloneApplication { // start CamelService val camelService = CamelService.newInstance.load - // access 'externally' registered active objects + // access 'externally' registered typed actors assert("hello msg1" == context.createProducerTemplate.requestBody("direct:test1", "msg1")) assert("hello msg2" == context.createProducerTemplate.requestBody("direct:test2", "msg2")) - // 'internally' register active object (requires CamelService) - ActiveObject.newInstance(classOf[ConsumerPojo2]) + // 'internally' register typed actor (requires CamelService) + TypedActor.newInstance(classOf[ConsumerPojo2], classOf[ConsumerPojo2Impl]) // internal registration is done in background. Wait a bit ... Thread.sleep(1000) @@ -52,7 +51,7 @@ object StandaloneApplication { class StandaloneApplicationRoute extends RouteBuilder { def configure = { - // routes to active objects (in SimpleRegistry) + // routes to typed actors (in SimpleRegistry) from("direct:test1").to("active-object:pojo1?method=foo") from("direct:test2").to("active-object:pojo2?method=foo") } @@ -65,7 +64,7 @@ object StandaloneSpringApplication { // load Spring application context val appctx = new ClassPathXmlApplicationContext("/context-standalone.xml") - // access 'externally' registered active objects with active-object component + // access 'externally' registered typed actors with active-object component assert("hello msg3" == template.requestBody("direct:test3", "msg3")) // destroy Spring application context @@ -78,7 +77,7 @@ object StandaloneSpringApplication { class StandaloneSpringApplicationRoute extends RouteBuilder { def configure = { - // routes to active object (in ApplicationContextRegistry) + // routes to typed actor (in ApplicationContextRegistry) from("direct:test3").to("active-object:pojo3?method=foo") } } diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java index 60eb4f11af..cd382ae6ec 100644 --- a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java @@ -4,11 +4,11 @@ package sample.rest.java; -import se.scalablesolutions.akka.config.ActiveObjectConfigurator; +import se.scalablesolutions.akka.config.TypedActorConfigurator; import static se.scalablesolutions.akka.config.JavaConfig.*; public class Boot { - public final static ActiveObjectConfigurator configurator = new ActiveObjectConfigurator(); + public final static TypedActorConfigurator configurator = new TypedActorConfigurator(); static { configurator.configure( new RestartStrategy(new OneForOne(), 3, 5000, new Class[]{Exception.class}), diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/PersistentSimpleService.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/PersistentSimpleService.java index 1108fcdb63..67368ceedd 100644 --- a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/PersistentSimpleService.java +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/PersistentSimpleService.java @@ -4,42 +4,6 @@ package sample.rest.java; -import se.scalablesolutions.akka.actor.annotation.transactionrequired; -import se.scalablesolutions.akka.actor.annotation.prerestart; -import se.scalablesolutions.akka.actor.annotation.postrestart; -import se.scalablesolutions.akka.persistence.common.PersistentMap; -import se.scalablesolutions.akka.persistence.cassandra.CassandraStorage; - -import java.nio.ByteBuffer; - -@transactionrequired -public class PersistentSimpleService { - private String KEY = "COUNTER"; - - private boolean hasStartedTicking = false; - private PersistentMap storage; - - public String count() { - if (storage == null) storage = CassandraStorage.newMap(); - if (!hasStartedTicking) { - storage.put(KEY.getBytes(), ByteBuffer.allocate(4).putInt(0).array()); - hasStartedTicking = true; - return "Tick: 0\n"; - } else { - byte[] bytes = (byte[])storage.get(KEY.getBytes()).get(); - int counter = ByteBuffer.wrap(bytes).getInt(); - storage.put(KEY.getBytes(), ByteBuffer.allocate(4).putInt(counter + 1).array()); - return "Tick: " + counter + "\n"; - } - } - - @prerestart - public void preRestart() { - System.out.println("Prepare for restart by supervisor"); - } - - @postrestart - public void postRestart() { - System.out.println("Reinitialize after restart by supervisor"); - } +public interface PersistentSimpleService { + public String count(); } \ No newline at end of file diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/PersistentSimpleServiceImpl.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/PersistentSimpleServiceImpl.java new file mode 100644 index 0000000000..2b83f4acbb --- /dev/null +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/PersistentSimpleServiceImpl.java @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package sample.rest.java; + +import se.scalablesolutions.akka.actor.TypedTransactor; +import se.scalablesolutions.akka.persistence.common.PersistentMap; +import se.scalablesolutions.akka.persistence.cassandra.CassandraStorage; + +import java.nio.ByteBuffer; + +public class PersistentSimpleServiceImpl extends TypedTransactor implements PersistentSimpleService { + private String KEY = "COUNTER"; + + private boolean hasStartedTicking = false; + private PersistentMap storage; + + public String count() { + if (storage == null) storage = CassandraStorage.newMap(); + if (!hasStartedTicking) { + storage.put(KEY.getBytes(), ByteBuffer.allocate(4).putInt(0).array()); + hasStartedTicking = true; + return "Tick: 0\n"; + } else { + byte[] bytes = (byte[])storage.get(KEY.getBytes()).get(); + int counter = ByteBuffer.wrap(bytes).getInt(); + storage.put(KEY.getBytes(), ByteBuffer.allocate(4).putInt(counter + 1).array()); + return "Tick: " + counter + "\n"; + } + } + + @Override + public void preRestart(Throwable cause) { + System.out.println("Prepare for restart by supervisor"); + } + + @Override + public void postRestart(Throwable cause) { + System.out.println("Reinitialize after restart by supervisor"); + } +} \ No newline at end of file diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Receiver.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Receiver.java index 06631659a2..4c60e44ae6 100644 --- a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Receiver.java +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Receiver.java @@ -4,17 +4,6 @@ package sample.rest.java; -import javax.ws.rs.Path; -import javax.ws.rs.GET; -import javax.ws.rs.Produces; - -import se.scalablesolutions.akka.actor.ActiveObject; -import se.scalablesolutions.akka.actor.ActiveObjectContext; - -public class Receiver { - private ActiveObjectContext context = null; - public SimpleService receive() { - System.out.println("------ RECEIVE"); - return (SimpleService) context.getSender(); - } +public interface Receiver { + SimpleService receive(); } diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/ReceiverImpl.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/ReceiverImpl.java new file mode 100644 index 0000000000..c46042a848 --- /dev/null +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/ReceiverImpl.java @@ -0,0 +1,14 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package sample.rest.java; + +import se.scalablesolutions.akka.actor.TypedActorContext; +import se.scalablesolutions.akka.actor.TypedActor; + +public class ReceiverImpl extends TypedActor implements Receiver { + public SimpleService receive() { + return (SimpleService) getContext().getSender(); + } +} diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/SimpleService.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/SimpleService.java index 097ba810b5..8055b3383a 100644 --- a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/SimpleService.java +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/SimpleService.java @@ -4,43 +4,6 @@ package sample.rest.java; -import se.scalablesolutions.akka.actor.ActiveObject; -import se.scalablesolutions.akka.actor.ActiveObjectContext; -import se.scalablesolutions.akka.actor.annotation.transactionrequired; -import se.scalablesolutions.akka.actor.annotation.prerestart; -import se.scalablesolutions.akka.actor.annotation.postrestart; -import se.scalablesolutions.akka.stm.TransactionalMap; - -@transactionrequired -public class SimpleService { - private String KEY = "COUNTER"; - - private boolean hasStartedTicking = false; - private TransactionalMap storage; - private Receiver receiver = ActiveObject.newInstance(Receiver.class); - - public String count() { - if (storage == null) storage = new TransactionalMap(); - if (!hasStartedTicking) { - storage.put(KEY, 0); - hasStartedTicking = true; - return "Tick: 0\n"; - } else { - // Grabs the sender address and returns it - //SimpleService sender = receiver.receive(); - int counter = (Integer)storage.get(KEY).get() + 1; - storage.put(KEY, counter); - return "Tick: " + counter + "\n"; - } - } - - @prerestart - public void preRestart() { - System.out.println("Prepare for restart by supervisor"); - } - - @postrestart - public void postRestart() { - System.out.println("Reinitialize after restart by supervisor"); - } +public interface SimpleService { + public String count(); } \ No newline at end of file diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/SimpleServiceImpl.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/SimpleServiceImpl.java new file mode 100644 index 0000000000..96400a0404 --- /dev/null +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/SimpleServiceImpl.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package sample.rest.java; + +import se.scalablesolutions.akka.actor.TypedActor; +import se.scalablesolutions.akka.actor.TypedTransactor; +import se.scalablesolutions.akka.actor.TypedActorContext; +import se.scalablesolutions.akka.stm.TransactionalMap; + +public class SimpleServiceImpl extends TypedTransactor implements SimpleService { + private String KEY = "COUNTER"; + + private boolean hasStartedTicking = false; + private TransactionalMap storage; + private Receiver receiver = TypedActor.newInstance(Receiver.class, ReceiverImpl.class); + + public String count() { + if (storage == null) storage = new TransactionalMap(); + if (!hasStartedTicking) { + storage.put(KEY, 0); + hasStartedTicking = true; + return "Tick: 0\n"; + } else { + // Grabs the sender address and returns it + //SimpleService sender = receiver.receive(); + int counter = (Integer)storage.get(KEY).get() + 1; + storage.put(KEY, counter); + return "Tick: " + counter + "\n"; + } + } + + @Override + public void preRestart(Throwable cause) { + System.out.println("Prepare for restart by supervisor"); + } + + @Override + public void postRestart(Throwable cause) { + System.out.println("Reinitialize after restart by supervisor"); + } +} \ No newline at end of file diff --git a/akka-spring/akka-spring-test-java/src/main/resources/se/scalablesolutions/akka/spring/foo/test-config.xml b/akka-spring/akka-spring-test-java/src/main/resources/se/scalablesolutions/akka/spring/foo/test-config.xml index 665d03a05e..13c45e6d3b 100644 --- a/akka-spring/akka-spring-test-java/src/main/resources/se/scalablesolutions/akka/spring/foo/test-config.xml +++ b/akka-spring/akka-spring-test-java/src/main/resources/se/scalablesolutions/akka/spring/foo/test-config.xml @@ -10,7 +10,7 @@ http://www.akkasource.org/schema/akka http://scalablesolutions.se/akka/akka-0.10.xsd"> diff --git a/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/SupervisorConfigurationTest.java b/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/SupervisorConfigurationTest.java index 659433cb9f..c90fd56b72 100644 --- a/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/SupervisorConfigurationTest.java +++ b/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/SupervisorConfigurationTest.java @@ -13,8 +13,8 @@ import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; -import se.scalablesolutions.akka.actor.ActiveObject; -import se.scalablesolutions.akka.config.ActiveObjectConfigurator; +import se.scalablesolutions.akka.actor.TypedActor; +import se.scalablesolutions.akka.config.TypedActorConfigurator; import se.scalablesolutions.akka.config.JavaConfig.AllForOne; import se.scalablesolutions.akka.config.JavaConfig.Component; import se.scalablesolutions.akka.config.JavaConfig.LifeCycle; @@ -45,10 +45,10 @@ public class SupervisorConfigurationTest { @Test public void testSupervision() { - // get ActiveObjectConfigurator bean from spring context - ActiveObjectConfigurator myConfigurator = (ActiveObjectConfigurator) context + // get TypedActorConfigurator bean from spring context + TypedActorConfigurator myConfigurator = (TypedActorConfigurator) context .getBean("supervision1"); - // get ActiveObjects + // get TypedActors Foo foo = myConfigurator.getInstance(Foo.class); assertNotNull(foo); IBar bar = myConfigurator.getInstance(IBar.class); @@ -59,7 +59,7 @@ public class SupervisorConfigurationTest { @Test public void testTransactionalState() { - ActiveObjectConfigurator conf = (ActiveObjectConfigurator) context + TypedActorConfigurator conf = (TypedActorConfigurator) context .getBean("supervision2"); StatefulPojo stateful = conf.getInstance(StatefulPojo.class); stateful.setMapState("testTransactionalState", "some map state"); @@ -73,23 +73,23 @@ public class SupervisorConfigurationTest { @Test public void testInitTransactionalState() { - StatefulPojo stateful = ActiveObject.newInstance(StatefulPojo.class, + StatefulPojo stateful = TypedActor.newInstance(StatefulPojo.class, 1000, true); assertTrue("should be inititalized", stateful.isInitialized()); } @Test public void testSupervisionWithDispatcher() { - ActiveObjectConfigurator myConfigurator = (ActiveObjectConfigurator) context + TypedActorConfigurator myConfigurator = (TypedActorConfigurator) context .getBean("supervision-with-dispatcher"); - // get ActiveObjects + // get TypedActors Foo foo = myConfigurator.getInstance(Foo.class); assertNotNull(foo); // TODO how to check dispatcher? } @Test - public void testRemoteActiveObject() { + public void testRemoteTypedActor() { new Thread(new Runnable() { public void run() { RemoteNode.start(); @@ -99,13 +99,13 @@ public class SupervisorConfigurationTest { Thread.currentThread().sleep(1000); } catch (Exception e) { } - Foo instance = ActiveObject.newRemoteInstance(Foo.class, 2000, "localhost", 9999); + Foo instance = TypedActor.newRemoteInstance(Foo.class, 2000, "localhost", 9999); System.out.println(instance.foo()); } @Test - public void testSupervisedRemoteActiveObject() { + public void testSupervisedRemoteTypedActor() { new Thread(new Runnable() { public void run() { RemoteNode.start(); @@ -116,7 +116,7 @@ public class SupervisorConfigurationTest { } catch (Exception e) { } - ActiveObjectConfigurator conf = new ActiveObjectConfigurator(); + TypedActorConfigurator conf = new TypedActorConfigurator(); conf.configure( new RestartStrategy(new AllForOne(), 3, 10000, new Class[] { Exception.class }), new Component[] { diff --git a/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/ActiveObjectConfigurationTest.java b/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/TypedActorConfigurationTest.java similarity index 89% rename from akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/ActiveObjectConfigurationTest.java rename to akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/TypedActorConfigurationTest.java index 7cc691f3e3..4117347380 100644 --- a/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/ActiveObjectConfigurationTest.java +++ b/akka-spring/akka-spring-test-java/src/test/java/se/scalablesolutions/akka/spring/TypedActorConfigurationTest.java @@ -21,10 +21,10 @@ import se.scalablesolutions.akka.remote.RemoteNode; import se.scalablesolutions.akka.spring.foo.MyPojo; /** - * Tests for spring configuration of active objects and supervisor configuration. + * Tests for spring configuration of typed actors and supervisor configuration. * @author michaelkober */ -public class ActiveObjectConfigurationTest { +public class TypedActorConfigurationTest { private ApplicationContext context = null; @@ -50,7 +50,7 @@ public class ActiveObjectConfigurationTest { } @Test - public void testSimpleActiveObject() { + public void testSimpleTypedActor() { MyPojo myPojo = (MyPojo) context.getBean("simple-active-object"); String msg = myPojo.getFoo(); msg += myPojo.getBar(); @@ -58,20 +58,20 @@ public class ActiveObjectConfigurationTest { } @Test(expected = FutureTimeoutException.class) - public void testSimpleActiveObject_Timeout() { + public void testSimpleTypedActor_Timeout() { MyPojo myPojo = (MyPojo) context.getBean("simple-active-object"); myPojo.longRunning(); } @Test - public void testSimpleActiveObject_NoTimeout() { + public void testSimpleTypedActor_NoTimeout() { MyPojo myPojo = (MyPojo) context.getBean("simple-active-object-long-timeout"); String msg = myPojo.longRunning(); assertEquals("this took long", msg); } @Test - public void testTransactionalActiveObject() { + public void testTransactionalTypedActor() { MyPojo myPojo = (MyPojo) context.getBean("transactional-active-object"); String msg = myPojo.getFoo(); msg += myPojo.getBar(); @@ -79,7 +79,7 @@ public class ActiveObjectConfigurationTest { } @Test - public void testRemoteActiveObject() { + public void testRemoteTypedActor() { new Thread(new Runnable() { public void run() { RemoteNode.start(); diff --git a/akka-spring/src/main/resources/se/scalablesolutions/akka/spring/akka-0.10.xsd b/akka-spring/src/main/resources/se/scalablesolutions/akka/spring/akka-0.10.xsd index 6eb0ec48fa..5fd9b94c38 100644 --- a/akka-spring/src/main/resources/se/scalablesolutions/akka/spring/akka-0.10.xsd +++ b/akka-spring/src/main/resources/se/scalablesolutions/akka/spring/akka-0.10.xsd @@ -134,7 +134,7 @@ - + @@ -196,7 +196,7 @@ - + @@ -252,7 +252,7 @@ - + diff --git a/akka-spring/src/main/scala/ActiveObjectFactoryBean.scala b/akka-spring/src/main/scala/ActiveObjectFactoryBean.scala deleted file mode 100644 index 7e33d0176a..0000000000 --- a/akka-spring/src/main/scala/ActiveObjectFactoryBean.scala +++ /dev/null @@ -1,198 +0,0 @@ -/** - * Copyright (C) 2009-2010 Scalable Solutions AB - */ - -package se.scalablesolutions.akka.spring - -import java.beans.PropertyDescriptor -import java.lang.reflect.Method -import javax.annotation.PreDestroy -import javax.annotation.PostConstruct -import reflect.BeanProperty - -import org.springframework.beans.BeanWrapperImpl -import org.springframework.beans.BeanWrapper -import org.springframework.beans.BeanUtils -import org.springframework.beans.factory.BeanFactory -import org.springframework.beans.factory.config.AbstractFactoryBean -import org.springframework.context.{ApplicationContext,ApplicationContextAware} -import org.springframework.util.ReflectionUtils -import org.springframework.util.StringUtils - -import se.scalablesolutions.akka.actor.{ActiveObjectConfiguration, ActiveObject} -import se.scalablesolutions.akka.config.ScalaConfig.{ShutdownCallback, RestartCallbacks} -import se.scalablesolutions.akka.dispatch.MessageDispatcher -import se.scalablesolutions.akka.util.{Logging, Duration} - -/** - * Factory bean for active objects. - * - * @author michaelkober - * @author Johan Rask - * @author Martin Krasser - */ -class ActiveObjectFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with ApplicationContextAware { - import StringReflect._ - import AkkaSpringConfigurationTags._ - - @BeanProperty var target: String = "" - @BeanProperty var timeout: Long = _ - @BeanProperty var interface: String = "" - @BeanProperty var transactional: Boolean = false - @BeanProperty var pre: String = "" - @BeanProperty var post: String = "" - @BeanProperty var shutdown: String = "" - @BeanProperty var host: String = "" - @BeanProperty var port: Int = _ - @BeanProperty var lifecycle: String = "" - @BeanProperty var dispatcher: DispatcherProperties = _ - @BeanProperty var scope:String = VAL_SCOPE_SINGLETON - @BeanProperty var property:PropertyEntries = _ - @BeanProperty var applicationContext:ApplicationContext = _ - - // Holds info about if deps has been set or not. Depends on - // if interface is specified or not. We must set deps on - // target instance if interface is specified - var hasSetDependecies = false - - - override def isSingleton:Boolean = { - if(scope.equals(VAL_SCOPE_SINGLETON)) { - true - } else { - false - } - } - - /* - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ - def getObjectType: Class[AnyRef] = try { - target.toClass - } catch { - // required by contract to return null - case e: ClassNotFoundException => null - } - - /* - * @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance() - */ - def createInstance: AnyRef = { - var argumentList = "" - if (isRemote) argumentList += "r" - if (hasInterface) argumentList += "i" - if (hasDispatcher) argumentList += "d" - - postConstruct( - setProperties( - create(argumentList))) - - } - - /** - * Stop the active object if it is a singleton. - */ - override def destroyInstance(instance:AnyRef) { - ActiveObject.stop(instance) - } - - /** - * Invokes any method annotated with @PostConstruct - * When interfaces are specified, this method is invoked both on the - * target instance and on the active object, so a developer is free do decide - * where the annotation should be. If no interface is specified it is only invoked - * on the active object - */ - private def postConstruct(ref:AnyRef) : AnyRef = { - // Invoke postConstruct method if any - for(method <- ref.getClass.getMethods) { - if(method.isAnnotationPresent(classOf[PostConstruct])) { - method.invoke(ref) - } - } - ref - } - - - private def setProperties(ref:AnyRef) : AnyRef = { - if(hasSetDependecies) { - return ref - } - - log.debug("Processing properties and dependencies for target class %s",target) - val beanWrapper = new BeanWrapperImpl(ref); - if(ref.isInstanceOf[ApplicationContextAware]) { - log.debug("Setting application context") - beanWrapper.setPropertyValue("applicationContext",applicationContext) - } - for(entry <- property.entryList) { - val propertyDescriptor = BeanUtils.getPropertyDescriptor(ref.getClass,entry.name) - val method = propertyDescriptor.getWriteMethod(); - - if(StringUtils.hasText(entry.ref)) { - log.debug("Setting property %s with bean ref %s using method %s", - entry.name,entry.ref,method.getName) - method.invoke(ref,getBeanFactory().getBean(entry.ref)) - } else if(StringUtils.hasText(entry.value)) { - log.debug("Setting property %s with value %s using method %s", - entry.name,entry.value,method.getName) - beanWrapper.setPropertyValue(entry.name,entry.value) - } else { - throw new AkkaBeansException("Either property@ref or property@value must be set on property element") - } - } - ref - } - - private[akka] def create(argList : String) : AnyRef = { - if (argList == "r") { - ActiveObject.newInstance(target.toClass, createConfig.makeRemote(host, port)) - } else if (argList == "ri" ) { - ActiveObject.newInstance(interface.toClass, aNewInstance(target.toClass), createConfig.makeRemote(host, port)) - } else if (argList == "rd") { - ActiveObject.newInstance(target.toClass, createConfig.makeRemote(host, port).dispatcher(dispatcherInstance)) - } else if (argList == "rid") { - ActiveObject.newInstance(interface.toClass, aNewInstance(target.toClass), createConfig.makeRemote(host, port).dispatcher(dispatcherInstance)) - } else if (argList == "i") { - ActiveObject.newInstance(interface.toClass, aNewInstance(target.toClass), createConfig) - } else if (argList == "id") { - ActiveObject.newInstance(interface.toClass, aNewInstance(target.toClass), createConfig.dispatcher(dispatcherInstance)) - } else if (argList == "d") { - ActiveObject.newInstance(target.toClass, createConfig.dispatcher(dispatcherInstance)) - } else { - ActiveObject.newInstance(target.toClass, createConfig) - } - } - - - - private[akka] def createConfig: ActiveObjectConfiguration = { - val config = new ActiveObjectConfiguration().timeout(Duration(timeout, "millis")) - if (hasRestartCallbacks) config.restartCallbacks(pre, post) - if (hasShutdownCallback) config.shutdownCallback(shutdown) - if (transactional) config.makeTransactionRequired - config - } - def aNewInstance[T <: AnyRef](clazz: Class[T]) : T = { - var ref = clazz.newInstance().asInstanceOf[T] - postConstruct( - setProperties(ref)) - hasSetDependecies = true - ref - } - - private[akka] def isRemote = (host != null) && (!host.isEmpty) - - private[akka] def hasInterface = (interface != null) && (!interface.isEmpty) - - private[akka] def hasRestartCallbacks = ((pre != null) && !pre.isEmpty) || ((post != null) && !post.isEmpty) - - private[akka] def hasShutdownCallback = ((shutdown != null) && !shutdown.isEmpty) - - private[akka] def hasDispatcher = (dispatcher != null) && (dispatcher.dispatcherType != null) && (!dispatcher.dispatcherType.isEmpty) - - private[akka] def dispatcherInstance : MessageDispatcher = { - import DispatcherFactoryBean._ - createNewInstance(dispatcher) - } -} diff --git a/akka-spring/src/main/scala/AkkaBeansException.scala b/akka-spring/src/main/scala/AkkaBeansException.scala deleted file mode 100644 index 8cbffa86f7..0000000000 --- a/akka-spring/src/main/scala/AkkaBeansException.scala +++ /dev/null @@ -1,14 +0,0 @@ -package se.scalablesolutions.akka.spring - -import org.springframework.beans.BeansException - -/** -* Exception to use when something goes wrong during bean creation -@author Johan Rask -*/ -class AkkaBeansException(errorMsg:String,t:Throwable) extends BeansException(errorMsg,t) { - - def this(errorMsg:String) = { - this(errorMsg,null) - } -} diff --git a/akka-spring/src/main/scala/AkkaNamespaceHandler.scala b/akka-spring/src/main/scala/AkkaNamespaceHandler.scala index 466dbeca30..34dede40aa 100644 --- a/akka-spring/src/main/scala/AkkaNamespaceHandler.scala +++ b/akka-spring/src/main/scala/AkkaNamespaceHandler.scala @@ -12,7 +12,7 @@ import AkkaSpringConfigurationTags._ */ class AkkaNamespaceHandler extends NamespaceHandlerSupport { def init = { - registerBeanDefinitionParser(ACTIVE_OBJECT_TAG, new ActiveObjectBeanDefinitionParser()); + registerBeanDefinitionParser(ACTIVE_OBJECT_TAG, new TypedActorBeanDefinitionParser()); registerBeanDefinitionParser(SUPERVISION_TAG, new SupervisionBeanDefinitionParser()); registerBeanDefinitionParser(DISPATCHER_TAG, new DispatcherBeanDefinitionParser()); registerBeanDefinitionParser(CAMEL_SERVICE_TAG, new CamelServiceBeanDefinitionParser); diff --git a/akka-spring/src/main/scala/AkkaSpringConfigurationTags.scala b/akka-spring/src/main/scala/AkkaSpringConfigurationTags.scala index 80a9f2e8d0..1e13865ad3 100644 --- a/akka-spring/src/main/scala/AkkaSpringConfigurationTags.scala +++ b/akka-spring/src/main/scala/AkkaSpringConfigurationTags.scala @@ -38,7 +38,7 @@ object AkkaSpringConfigurationTags { // --- ATTRIBUTES // - // active object attributes + // typed actor attributes val TIMEOUT = "timeout" val TARGET = "target" val INTERFACE = "interface" diff --git a/akka-spring/src/main/scala/DispatcherBeanDefinitionParser.scala b/akka-spring/src/main/scala/DispatcherBeanDefinitionParser.scala index 826125fcfc..9d4a16ff9b 100644 --- a/akka-spring/src/main/scala/DispatcherBeanDefinitionParser.scala +++ b/akka-spring/src/main/scala/DispatcherBeanDefinitionParser.scala @@ -12,7 +12,7 @@ import org.springframework.beans.factory.xml.{ParserContext, AbstractSingleBeanD * Parser for custom namespace configuration. * @author michaelkober */ -class DispatcherBeanDefinitionParser extends AbstractSingleBeanDefinitionParser with ActiveObjectParser with DispatcherParser { +class DispatcherBeanDefinitionParser extends AbstractSingleBeanDefinitionParser with TypedActorParser with DispatcherParser { /* * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder) */ diff --git a/akka-spring/src/main/scala/StringReflect.scala b/akka-spring/src/main/scala/StringReflect.scala index 7dda9dba08..ae32350e2d 100644 --- a/akka-spring/src/main/scala/StringReflect.scala +++ b/akka-spring/src/main/scala/StringReflect.scala @@ -1,9 +1,11 @@ /** * Copyright (C) 2009-2010 Scalable Solutions AB */ + package se.scalablesolutions.akka.spring object StringReflect { + /** * Implicit conversion from String to StringReflect. */ @@ -15,10 +17,9 @@ object StringReflect { * @author michaelkober */ class StringReflect(val self: String) { + if (self == null || self == "") throw new IllegalArgumentException("Class name can't be null or empty string [" + self + "]") def toClass[T <: AnyRef]: Class[T] = { val clazz = Class.forName(self) clazz.asInstanceOf[Class[T]] } -} - - +} \ No newline at end of file diff --git a/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala b/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala index dde14f3cb2..4a76f5b008 100644 --- a/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala +++ b/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala @@ -18,7 +18,7 @@ import org.springframework.util.xml.DomUtils * Parser for custom namespace for Akka declarative supervisor configuration. * @author michaelkober */ -class SupervisionBeanDefinitionParser extends AbstractSingleBeanDefinitionParser with ActiveObjectParser { +class SupervisionBeanDefinitionParser extends AbstractSingleBeanDefinitionParser with TypedActorParser { /* (non-Javadoc) * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder) */ @@ -33,7 +33,7 @@ class SupervisionBeanDefinitionParser extends AbstractSingleBeanDefinitionParser val strategyElement = mandatoryElement(element, STRATEGY_TAG); val activeObjectsElement = mandatoryElement(element, ACTIVE_OBJECTS_TAG); parseRestartStrategy(strategyElement, builder) - parseActiveObjectList(activeObjectsElement, builder) + parseTypedActorList(activeObjectsElement, builder) } private[akka] def parseRestartStrategy(element: Element, builder: BeanDefinitionBuilder) { @@ -46,9 +46,9 @@ class SupervisionBeanDefinitionParser extends AbstractSingleBeanDefinitionParser builder.addPropertyValue("restartStrategy", restartStrategy) } - private[akka] def parseActiveObjectList(element: Element, builder: BeanDefinitionBuilder) { + private[akka] def parseTypedActorList(element: Element, builder: BeanDefinitionBuilder) { val activeObjects = DomUtils.getChildElementsByTagName(element, ACTIVE_OBJECT_TAG).toArray.toList.asInstanceOf[List[Element]] - val activeObjectProperties = activeObjects.map(parseActiveObject(_)) + val activeObjectProperties = activeObjects.map(parseTypedActor(_)) builder.addPropertyValue("supervised", activeObjectProperties) } diff --git a/akka-spring/src/main/scala/SupervisionFactoryBean.scala b/akka-spring/src/main/scala/SupervisionFactoryBean.scala index d8c44c3502..80a1f8a5fa 100644 --- a/akka-spring/src/main/scala/SupervisionFactoryBean.scala +++ b/akka-spring/src/main/scala/SupervisionFactoryBean.scala @@ -4,7 +4,7 @@ package se.scalablesolutions.akka.spring import org.springframework.beans.factory.config.AbstractFactoryBean -import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.TypedActorConfigurator import se.scalablesolutions.akka.config.JavaConfig._ import AkkaSpringConfigurationTags._ import reflect.BeanProperty @@ -14,20 +14,20 @@ import reflect.BeanProperty * Factory bean for supervisor configuration. * @author michaelkober */ -class SupervisionFactoryBean extends AbstractFactoryBean[ActiveObjectConfigurator] { +class SupervisionFactoryBean extends AbstractFactoryBean[TypedActorConfigurator] { @BeanProperty var restartStrategy: RestartStrategy = _ - @BeanProperty var supervised: List[ActiveObjectProperties] = _ + @BeanProperty var supervised: List[TypedActorProperties] = _ /* * @see org.springframework.beans.factory.FactoryBean#getObjectType() */ - def getObjectType: Class[ActiveObjectConfigurator] = classOf[ActiveObjectConfigurator] + def getObjectType: Class[TypedActorConfigurator] = classOf[TypedActorConfigurator] /* * @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance() */ - def createInstance: ActiveObjectConfigurator = { - val configurator = new ActiveObjectConfigurator() + def createInstance: TypedActorConfigurator = { + val configurator = new TypedActorConfigurator() configurator.configure( restartStrategy, @@ -36,9 +36,9 @@ class SupervisionFactoryBean extends AbstractFactoryBean[ActiveObjectConfigurato } /** - * Create configuration for ActiveObject + * Create configuration for TypedActor */ - private[akka] def createComponent(props: ActiveObjectProperties): Component = { + private[akka] def createComponent(props: TypedActorProperties): Component = { import StringReflect._ val lifeCycle = if (!props.lifecycle.isEmpty && props.lifecycle.equalsIgnoreCase(VAL_LIFECYCYLE_TEMPORARY)) new LifeCycle(new Temporary()) else new LifeCycle(new Permanent()) val isRemote = (props.host != null) && (!props.host.isEmpty) diff --git a/akka-spring/src/main/scala/ActiveObjectBeanDefinitionParser.scala b/akka-spring/src/main/scala/TypedActorBeanDefinitionParser.scala similarity index 84% rename from akka-spring/src/main/scala/ActiveObjectBeanDefinitionParser.scala rename to akka-spring/src/main/scala/TypedActorBeanDefinitionParser.scala index 0189147994..7869a6a33f 100644 --- a/akka-spring/src/main/scala/ActiveObjectBeanDefinitionParser.scala +++ b/akka-spring/src/main/scala/TypedActorBeanDefinitionParser.scala @@ -13,17 +13,17 @@ import org.w3c.dom.Element * Parser for custom namespace configuration. * @author michaelkober */ -class ActiveObjectBeanDefinitionParser extends AbstractSingleBeanDefinitionParser with ActiveObjectParser { +class TypedActorBeanDefinitionParser extends AbstractSingleBeanDefinitionParser with TypedActorParser { /* * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder) */ override def doParse(element: Element, parserContext: ParserContext, builder: BeanDefinitionBuilder) { - val activeObjectConf = parseActiveObject(element) + val activeObjectConf = parseTypedActor(element) activeObjectConf.setAsProperties(builder) } /* * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element) */ - override def getBeanClass(element: Element): Class[_] = classOf[ActiveObjectFactoryBean] + override def getBeanClass(element: Element): Class[_] = classOf[TypedActorFactoryBean] } diff --git a/akka-spring/src/main/scala/TypedActorFactoryBean.scala b/akka-spring/src/main/scala/TypedActorFactoryBean.scala new file mode 100644 index 0000000000..7ba4cf5061 --- /dev/null +++ b/akka-spring/src/main/scala/TypedActorFactoryBean.scala @@ -0,0 +1,188 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.spring + +import java.beans.PropertyDescriptor +import java.lang.reflect.Method +import javax.annotation.PreDestroy +import javax.annotation.PostConstruct +import reflect.BeanProperty + +import org.springframework.beans.BeanWrapperImpl +import org.springframework.beans.BeanWrapper +import org.springframework.beans.BeanUtils +import org.springframework.beans.BeansException +import org.springframework.beans.factory.BeanFactory +import org.springframework.beans.factory.config.AbstractFactoryBean +import org.springframework.context.{ApplicationContext,ApplicationContextAware} +import org.springframework.util.ReflectionUtils +import org.springframework.util.StringUtils + +import se.scalablesolutions.akka.actor.{TypedActorConfiguration, TypedActor} +import se.scalablesolutions.akka.config.ScalaConfig.{ShutdownCallback, RestartCallbacks} +import se.scalablesolutions.akka.dispatch.MessageDispatcher +import se.scalablesolutions.akka.util.{Logging, Duration} + +/** + * Exception to use when something goes wrong during bean creation. + * + * @author Johan Rask + */ +class AkkaBeansException(message: String, cause:Throwable) extends BeansException(message, cause) { + def this(message: String) = this(message, null) +} + +/** + * Factory bean for typed actors. + * + * @author michaelkober + * @author Johan Rask + * @author Martin Krasser + * @author Jonas Bonér + */ +class TypedActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with ApplicationContextAware { + import StringReflect._ + import AkkaSpringConfigurationTags._ + + @BeanProperty var target: String = "" + @BeanProperty var timeout: Long = _ + @BeanProperty var interface: String = "" + @BeanProperty var transactional: Boolean = false + @BeanProperty var pre: String = "" + @BeanProperty var post: String = "" + @BeanProperty var shutdown: String = "" + @BeanProperty var host: String = "" + @BeanProperty var port: Int = _ + @BeanProperty var lifecycle: String = "" + @BeanProperty var dispatcher: DispatcherProperties = _ + @BeanProperty var scope: String = VAL_SCOPE_SINGLETON + @BeanProperty var property: PropertyEntries = _ + @BeanProperty var applicationContext: ApplicationContext = _ + + // Holds info about if deps has been set or not. Depends on + // if interface is specified or not. We must set deps on + // target instance if interface is specified + var hasSetDependecies = false + + override def isSingleton = scope.equals(VAL_SCOPE_SINGLETON) + + /* + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ + def getObjectType: Class[AnyRef] = try { + target.toClass + } catch { + // required by contract to return null + case e: ClassNotFoundException => null + } + + /* + * @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance() + */ + def createInstance: AnyRef = { + var argumentList = "" + if (isRemote) argumentList += "r" + if (hasInterface) argumentList += "i" + if (hasDispatcher) argumentList += "d" + postConstruct(setProperties(create(argumentList))) + } + + /** + * Stop the typed actor if it is a singleton. + */ + override def destroyInstance(instance: AnyRef) = TypedActor.stop(instance.asInstanceOf[TypedActor]) + + /** + * Invokes any method annotated with @PostConstruct + * When interfaces are specified, this method is invoked both on the + * target instance and on the typed actor, so a developer is free do decide + * where the annotation should be. If no interface is specified it is only invoked + * on the typed actor + */ + private def postConstruct(ref: AnyRef): AnyRef = { + // Invoke postConstruct method if any + for { + method <- ref.getClass.getMethods + if method.isAnnotationPresent(classOf[PostConstruct]) + } method.invoke(ref) + ref + } + + + private def setProperties(ref: AnyRef): AnyRef = { + if (hasSetDependecies) return ref + log.debug("Processing properties and dependencies for target class\n\t[%s]", target) + val beanWrapper = new BeanWrapperImpl(ref); + if (ref.isInstanceOf[ApplicationContextAware]) { + log.debug("Setting application context") + beanWrapper.setPropertyValue("applicationContext", applicationContext) + } + for (entry <- property.entryList) { + val propertyDescriptor = BeanUtils.getPropertyDescriptor(ref.getClass, entry.name) + val method = propertyDescriptor.getWriteMethod + if (StringUtils.hasText(entry.ref)) { + log.debug("Setting property %s with bean ref %s using method %s", entry.name, entry.ref, method.getName) + method.invoke(ref,getBeanFactory().getBean(entry.ref)) + } else if(StringUtils.hasText(entry.value)) { + log.debug("Setting property %s with value %s using method %s", entry.name, entry.value, method.getName) + beanWrapper.setPropertyValue(entry.name,entry.value) + } else throw new AkkaBeansException("Either property@ref or property@value must be set on property element") + } + ref + } + + private[akka] def create(argList: String): AnyRef = { + if (interface == null || interface == "") throw new AkkaBeansException( + "The 'interface' part of the 'akka:actor' element in the Spring config file can't be null or empty string") + if (target == null || target == "") throw new AkkaBeansException( + "The 'target' part of the 'akka:actor' element in the Spring config file can't be null or empty string") + argList match { + case "ri" => TypedActor.newInstance(interface.toClass, newInstanceFor(target.toClass), createConfig.makeRemote(host, port)) + case "i" => TypedActor.newInstance(interface.toClass, newInstanceFor(target.toClass), createConfig) + case "id" => TypedActor.newInstance(interface.toClass, newInstanceFor(target.toClass), createConfig.dispatcher(dispatcherInstance)) + case "rid" => TypedActor.newInstance(interface.toClass, newInstanceFor(target.toClass), + createConfig.makeRemote(host, port).dispatcher(dispatcherInstance)) + case _ => TypedActor.newInstance(interface.toClass, newInstanceFor(target.toClass), createConfig) + // case "rd" => TypedActor.newInstance(target.toClass, createConfig.makeRemote(host, port).dispatcher(dispatcherInstance)) + // case "r" => TypedActor.newInstance(target.toClass, createConfig.makeRemote(host, port)) + // case "d" => TypedActor.newInstance(target.toClass, createConfig.dispatcher(dispatcherInstance)) + } + } + + private[akka] def createConfig: TypedActorConfiguration = { + val config = new TypedActorConfiguration().timeout(Duration(timeout, "millis")) + if (hasRestartCallbacks) config.restartCallbacks(pre, post) + if (hasShutdownCallback) config.shutdownCallback(shutdown) + if (transactional) config.makeTransactionRequired + config + } + + def newInstanceFor[T <: AnyRef](clazz: Class[T]): T = { + var ref = clazz.newInstance().asInstanceOf[T] + postConstruct(setProperties(ref)) + hasSetDependecies = true + ref + } + + private[akka] def isRemote = (host != null) && (!host.isEmpty) + + private[akka] def hasInterface = (interface != null) && (!interface.isEmpty) + + private[akka] def hasRestartCallbacks = + ((pre != null) && !pre.isEmpty) || + ((post != null) && !post.isEmpty) + + private[akka] def hasShutdownCallback = ((shutdown != null) && !shutdown.isEmpty) + + private[akka] def hasDispatcher = + (dispatcher != null) && + (dispatcher.dispatcherType != null) && + (!dispatcher.dispatcherType.isEmpty) + + private[akka] def dispatcherInstance: MessageDispatcher = { + import DispatcherFactoryBean._ + createNewInstance(dispatcher) + } +} diff --git a/akka-spring/src/main/scala/ActiveObjectParser.scala b/akka-spring/src/main/scala/TypedActorParser.scala similarity index 90% rename from akka-spring/src/main/scala/ActiveObjectParser.scala rename to akka-spring/src/main/scala/TypedActorParser.scala index 8838360a44..43e713f00e 100644 --- a/akka-spring/src/main/scala/ActiveObjectParser.scala +++ b/akka-spring/src/main/scala/TypedActorParser.scala @@ -15,16 +15,16 @@ import se.scalablesolutions.akka.actor.IllegalActorStateException * @author Johan Rask * @author Martin Krasser */ -trait ActiveObjectParser extends BeanParser with DispatcherParser { +trait TypedActorParser extends BeanParser with DispatcherParser { import AkkaSpringConfigurationTags._ /** - * Parses the given element and returns a ActiveObjectProperties. + * Parses the given element and returns a TypedActorProperties. * @param element dom element to parse - * @return configuration for the active object + * @return configuration for the typed actor */ - def parseActiveObject(element: Element): ActiveObjectProperties = { - val objectProperties = new ActiveObjectProperties() + def parseTypedActor(element: Element): TypedActorProperties = { + val objectProperties = new TypedActorProperties() val remoteElement = DomUtils.getChildElementByTagName(element, REMOTE_TAG); val restartCallbacksElement = DomUtils.getChildElementByTagName(element, RESTART_CALLBACKS_TAG); val shutdownCallbackElement = DomUtils.getChildElementByTagName(element, SHUTDOWN_CALLBACK_TAG); diff --git a/akka-spring/src/main/scala/ActiveObjectProperties.scala b/akka-spring/src/main/scala/TypedActorProperties.scala similarity index 94% rename from akka-spring/src/main/scala/ActiveObjectProperties.scala rename to akka-spring/src/main/scala/TypedActorProperties.scala index 0f4b09d559..53f2fca05a 100644 --- a/akka-spring/src/main/scala/ActiveObjectProperties.scala +++ b/akka-spring/src/main/scala/TypedActorProperties.scala @@ -8,11 +8,11 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder import AkkaSpringConfigurationTags._ /** - * Data container for active object configuration data. + * Data container for typed actor configuration data. * @author michaelkober * @author Martin Krasser */ -class ActiveObjectProperties { +class TypedActorProperties { var target: String = "" var timeout: Long = _ var interface: String = "" diff --git a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/Pojo.java b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/Pojo.java index 04995b75c8..72fb8cb895 100644 --- a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/Pojo.java +++ b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/Pojo.java @@ -2,38 +2,41 @@ package se.scalablesolutions.akka.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; + import javax.annotation.PreDestroy; import javax.annotation.PostConstruct; -public class Pojo implements PojoInf,ApplicationContextAware { +import se.scalablesolutions.akka.actor.*; + +public class Pojo extends TypedActor implements PojoInf, ApplicationContextAware { private String string; - private boolean gotApplicationContext = false; - private boolean postConstructInvoked = false; - - public boolean gotApplicationContext() { - return gotApplicationContext; - } - public void setApplicationContext(ApplicationContext context) { - gotApplicationContext = true; - } + private boolean gotApplicationContext = false; + private boolean postConstructInvoked = false; + + public boolean gotApplicationContext() { + return gotApplicationContext; + } + + public void setApplicationContext(ApplicationContext context) { + gotApplicationContext = true; + } - public void setString(String s) { - string = s; - } + public void setString(String s) { + string = s; + } public String getString() { - return string; - } - - @PostConstruct - public void create() { - postConstructInvoked = true; - } + return string; + } - public boolean isPostConstructInvoked() { - return postConstructInvoked; + @PostConstruct + public void create() { + postConstructInvoked = true; + } + + public boolean isPostConstructInvoked() { + return postConstructInvoked; + } } - - } diff --git a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/PojoInf.java b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/PojoInf.java index 70d64245db..0189d5ec4a 100644 --- a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/PojoInf.java +++ b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/PojoInf.java @@ -5,10 +5,10 @@ import javax.annotation.PostConstruct; public interface PojoInf { - public String getString(); - public boolean gotApplicationContext(); - public boolean isPostConstructInvoked(); - - @PostConstruct - public void create(); - } + public String getString(); + public boolean gotApplicationContext(); + public boolean isPostConstructInvoked(); + + @PostConstruct + public void create(); +} diff --git a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleBean.java b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleBean.java index e8adaa38e7..2828c42bcb 100644 --- a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleBean.java +++ b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleBean.java @@ -1,22 +1,25 @@ package se.scalablesolutions.akka.spring; -import se.scalablesolutions.akka.actor.annotation.shutdown; +import se.scalablesolutions.akka.actor.*; -public class SampleBean { +public class SampleBean extends TypedActor implements SampleBeanIntf { - public boolean down; + private boolean down; public SampleBean() { down = false; } + public boolean down() { + return down; + } + public String foo(String s) { return "hello " + s; } - @shutdown + @Override public void shutdown() { down = true; } - } diff --git a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleBeanIntf.java b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleBeanIntf.java new file mode 100644 index 0000000000..ec189ecd5f --- /dev/null +++ b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleBeanIntf.java @@ -0,0 +1,6 @@ +package se.scalablesolutions.akka.spring; + +public interface SampleBeanIntf { + public boolean down(); + public String foo(String s); + } diff --git a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleRoute.java b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleRoute.java index 3865ea1615..84377ee3d6 100644 --- a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleRoute.java +++ b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/SampleRoute.java @@ -8,5 +8,4 @@ public class SampleRoute extends RouteBuilder { public void configure() throws Exception { from("direct:test").to("active-object:sample?method=foo"); } - } diff --git a/akka-spring/src/test/resources/appContext.xml b/akka-spring/src/test/resources/appContext.xml index e9a651b735..ba2c243558 100644 --- a/akka-spring/src/test/resources/appContext.xml +++ b/akka-spring/src/test/resources/appContext.xml @@ -7,27 +7,37 @@ http://www.akkasource.org/schema/akka http://scalablesolutions.se/akka/akka-0.10.xsd"> - - - + + + - + + + + + + + + diff --git a/akka-spring/src/test/resources/appContextCamelServiceCustom.xml b/akka-spring/src/test/resources/appContextCamelServiceCustom.xml index ba18a325d0..7150465e7c 100644 --- a/akka-spring/src/test/resources/appContextCamelServiceCustom.xml +++ b/akka-spring/src/test/resources/appContextCamelServiceCustom.xml @@ -20,6 +20,8 @@ http://camel.apache.org/schema/spring/camel-spring.xsd"> - - + diff --git a/akka-spring/src/test/resources/failing-appContext.xml b/akka-spring/src/test/resources/failing-appContext.xml index 1acab0e830..bc970b6036 100644 --- a/akka-spring/src/test/resources/failing-appContext.xml +++ b/akka-spring/src/test/resources/failing-appContext.xml @@ -7,15 +7,15 @@ http://www.akkasource.org/schema/akka classpath:se/scalablesolutions/akka/spring/akka-0.10.xsd"> - - - - - - - + + + + + + + \ No newline at end of file diff --git a/akka-spring/src/test/scala/CamelServiceSpringFeatureTest.scala b/akka-spring/src/test/scala/CamelServiceSpringFeatureTest.scala index d260afa44f..ff246891c9 100644 --- a/akka-spring/src/test/scala/CamelServiceSpringFeatureTest.scala +++ b/akka-spring/src/test/scala/CamelServiceSpringFeatureTest.scala @@ -6,7 +6,7 @@ import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach, FeatureSpec} import org.springframework.context.support.ClassPathXmlApplicationContext import se.scalablesolutions.akka.camel.CamelContextManager -import se.scalablesolutions.akka.actor.{ActiveObject, ActorRegistry} +import se.scalablesolutions.akka.actor.{TypedActor, ActorRegistry} class CamelServiceSpringFeatureTest extends FeatureSpec with BeforeAndAfterEach with BeforeAndAfterAll { override protected def beforeAll = { @@ -17,27 +17,28 @@ class CamelServiceSpringFeatureTest extends FeatureSpec with BeforeAndAfterEach ActorRegistry.shutdownAll } +/* feature("start CamelService from Spring application context") { import CamelContextManager._ - - scenario("with a custom CamelContext and access a registered active object") { + scenario("with a custom CamelContext and access a registered typed actor") { val appctx = new ClassPathXmlApplicationContext("/appContextCamelServiceCustom.xml") assert(context.isInstanceOf[SpringCamelContext]) assert("hello sample" === template.requestBody("direct:test", "sample")) appctx.close } - scenario("with a default CamelContext and access a registered active object") { + scenario("with a default CamelContext and access a registered typed actor") { val appctx = new ClassPathXmlApplicationContext("/appContextCamelServiceDefault.xml") // create a custom registry val registry = new SimpleRegistry - registry.put("custom", ActiveObject.newInstance(classOf[SampleBean])) + registry.put("custom", TypedActor.newInstance(classOf[SampleBeanIntf], classOf[SampleBean])) // set custom registry in DefaultCamelContext assert(context.isInstanceOf[DefaultCamelContext]) context.asInstanceOf[DefaultCamelContext].setRegistry(registry) - // access registered active object + // access registered typed actor assert("hello sample" === template.requestBody("active-object:custom?method=foo", "sample")) appctx.close } } +*/ } diff --git a/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala b/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala index bd5490a1b0..64e9ea2425 100644 --- a/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala +++ b/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala @@ -89,7 +89,7 @@ class DispatcherBeanDefinitionParserTest extends Spec with ShouldMatchers { } - it("should throw IllegalArgumentException when configuring a thread based dispatcher without ActiveObject") { + it("should throw IllegalArgumentException when configuring a thread based dispatcher without TypedActor") { val xml = evaluating { parser.parseDispatcher(dom(xml).getDocumentElement) } should produce [IllegalArgumentException] } diff --git a/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala b/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala index ffc1f7a95d..317421c207 100644 --- a/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala +++ b/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala @@ -26,8 +26,8 @@ class SupervisionBeanDefinitionParserTest extends Spec with ShouldMatchers { val parser = new Parser() val builder = BeanDefinitionBuilder.genericBeanDefinition("foo.bar.Foo") - it("should be able to parse active object configuration") { - val props = parser.parseActiveObject(createActiveObjectElement); + it("should be able to parse typed actor configuration") { + val props = parser.parseTypedActor(createTypedActorElement); assert(props != null) assert(props.timeout == 1000) assert(props.target == "foo.bar.MyPojo") @@ -45,9 +45,9 @@ class SupervisionBeanDefinitionParserTest extends Spec with ShouldMatchers { expect(1000) { strategy.withinTimeRange } } - it("should parse the supervised active objects") { + it("should parse the supervised typed actors") { parser.parseSupervisor(createSupervisorElement, builder); - val supervised = builder.getBeanDefinition.getPropertyValues.getPropertyValue("supervised").getValue.asInstanceOf[List[ActiveObjectProperties]] + val supervised = builder.getBeanDefinition.getPropertyValues.getPropertyValue("supervised").getValue.asInstanceOf[List[TypedActorProperties]] assert(supervised != null) expect(4) { supervised.length } val iterator = supervised.iterator @@ -75,7 +75,7 @@ class SupervisionBeanDefinitionParserTest extends Spec with ShouldMatchers { } } - private def createActiveObjectElement : Element = { + private def createTypedActorElement : Element = { val xml = - val props = parser.parseActiveObject(dom(xml).getDocumentElement); + val props = parser.parseTypedActor(dom(xml).getDocumentElement); assert(props != null) assert(props.timeout === 1000) assert(props.target === "foo.bar.MyPojo") @@ -44,25 +44,25 @@ class ActiveObjectBeanDefinitionParserTest extends Spec with ShouldMatchers { timeout="1000" transactional="true"/> - evaluating { parser.parseActiveObject(dom(xml).getDocumentElement) } should produce [IllegalArgumentException] + evaluating { parser.parseTypedActor(dom(xml).getDocumentElement) } should produce [IllegalArgumentException] } - it("should parse ActiveObjects configuration with dispatcher") { + it("should parse TypedActors configuration with dispatcher") { val xml = - val props = parser.parseActiveObject(dom(xml).getDocumentElement); + val props = parser.parseTypedActor(dom(xml).getDocumentElement); assert(props != null) assert(props.dispatcher.dispatcherType === "thread-based") } - it("should parse remote ActiveObjects configuration") { + it("should parse remote TypedActors configuration") { val xml = - val props = parser.parseActiveObject(dom(xml).getDocumentElement); + val props = parser.parseTypedActor(dom(xml).getDocumentElement); assert(props != null) assert(props.host === "com.some.host") assert(props.port === 9999) diff --git a/akka-spring/src/test/scala/ActiveObjectFactoryBeanTest.scala b/akka-spring/src/test/scala/TypedActorFactoryBeanTest.scala similarity index 74% rename from akka-spring/src/test/scala/ActiveObjectFactoryBeanTest.scala rename to akka-spring/src/test/scala/TypedActorFactoryBeanTest.scala index 68dac8e97c..9fb500240b 100644 --- a/akka-spring/src/test/scala/ActiveObjectFactoryBeanTest.scala +++ b/akka-spring/src/test/scala/TypedActorFactoryBeanTest.scala @@ -11,14 +11,14 @@ import org.springframework.core.io.ResourceEditor import org.springframework.context.support.ClassPathXmlApplicationContext; /** - * Test for ActiveObjectFactoryBean + * Test for TypedActorFactoryBean * @author michaelkober */ @RunWith(classOf[JUnitRunner]) -class ActiveObjectFactoryBeanTest extends Spec with ShouldMatchers { +class TypedActorFactoryBeanTest extends Spec with ShouldMatchers { - describe("A ActiveObjectFactoryBean") { - val bean = new ActiveObjectFactoryBean + describe("A TypedActorFactoryBean") { + val bean = new TypedActorFactoryBean it("should have java getters and setters for all properties") { bean.setTarget("java.lang.String") assert(bean.getTarget == "java.lang.String") @@ -26,7 +26,7 @@ class ActiveObjectFactoryBeanTest extends Spec with ShouldMatchers { assert(bean.getTimeout == 1000) } - it("should create a remote active object when a host is set") { + it("should create a remote typed actor when a host is set") { bean.setHost("some.host.com"); assert(bean.isRemote) } @@ -36,7 +36,7 @@ class ActiveObjectFactoryBeanTest extends Spec with ShouldMatchers { assert(bean.hasInterface) } - it("should create an active object with dispatcher if dispatcher is set") { + it("should create an typed actor with dispatcher if dispatcher is set") { val props = new DispatcherProperties() props.dispatcherType = "executor-based-event-driven" bean.setDispatcher(props); @@ -48,8 +48,43 @@ class ActiveObjectFactoryBeanTest extends Spec with ShouldMatchers { assert(bean.getObjectType == classOf[String]) } +/* + it("should create an application context and verify dependency injection") { + var ctx = new ClassPathXmlApplicationContext("appContext.xml"); + val target:ResourceEditor = ctx.getBean("bean").asInstanceOf[ResourceEditor] + assert(target.getSource === "someString") + + val pojoInf = ctx.getBean("pojoInf").asInstanceOf[PojoInf]; + Thread.sleep(200) + assert(pojoInf.isPostConstructInvoked) + assert(pojoInf.getString == "akka rocks") + assert(pojoInf.gotApplicationContext) + } + + it("should stop the created typed actor when scope is singleton and the context is closed") { + var ctx = new ClassPathXmlApplicationContext("appContext.xml"); + val target = ctx.getBean("bean-singleton").asInstanceOf[SampleBean] + assert(!target.down) + ctx.close + assert(target.down) + } + + it("should not stop the created typed actor when scope is prototype and the context is closed") { + var ctx = new ClassPathXmlApplicationContext("appContext.xml"); + val target = ctx.getBean("bean-prototype").asInstanceOf[SampleBean] + assert(!target.down) + ctx.close + assert(!target.down) + } + */ + } +} + +/* + // ------ NOTE: Can't work now when we only support POJO with interface ----- + it("should create a proxy of type ResourceEditor") { - val bean = new ActiveObjectFactoryBean() + val bean = new TypedActorFactoryBean() // we must have a java class here bean.setTarget("org.springframework.core.io.ResourceEditor") val entries = new PropertyEntries() @@ -64,34 +99,4 @@ class ActiveObjectFactoryBeanTest extends Spec with ShouldMatchers { val target:ResourceEditor = bean.createInstance.asInstanceOf[ResourceEditor] assert(target.getSource === entry.value) } - - it("should create an application context and verify dependency injection") { - var ctx = new ClassPathXmlApplicationContext("appContext.xml"); - val target:ResourceEditor = ctx.getBean("bean").asInstanceOf[ResourceEditor] - assert(target.getSource === "someString") - - val pojoInf = ctx.getBean("pojoInf").asInstanceOf[PojoInf]; - println("pojoInf = " + pojoInf.getString) - Thread.sleep(200) - assert(pojoInf.isPostConstructInvoked) - assert(pojoInf.getString == "akka rocks") - assert(pojoInf.gotApplicationContext) - } - - it("should stop the created active object when scope is singleton and the context is closed") { - var ctx = new ClassPathXmlApplicationContext("appContext.xml"); - val target = ctx.getBean("bean-singleton").asInstanceOf[SampleBean] - assert(!target.down) - ctx.close - assert(target.down) - } - - it("should not stop the created active object when scope is prototype and the context is closed") { - var ctx = new ClassPathXmlApplicationContext("appContext.xml"); - val target = ctx.getBean("bean-prototype").asInstanceOf[SampleBean] - assert(!target.down) - ctx.close - assert(!target.down) - } - } -} +*/ diff --git a/config/akka-reference.conf b/config/akka-reference.conf index a3cb3467b0..ec5f85355f 100644 --- a/config/akka-reference.conf +++ b/config/akka-reference.conf @@ -24,7 +24,7 @@ akka { time-unit = "seconds" # default timeout time unit for all timeout properties throughout the config - # FQN (Fully Qualified Name) to the class doing initial active object/actor + # FQN (Fully Qualified Name) to the class doing initial typed actor/actor # supervisor bootstrap, should be defined in default constructor boot = ["sample.camel.Boot", "sample.rest.java.Boot", diff --git a/project/build/AkkaProject.scala b/project/build/AkkaProject.scala index 3967bf81ce..6dce71b7b3 100644 --- a/project/build/AkkaProject.scala +++ b/project/build/AkkaProject.scala @@ -591,7 +591,7 @@ class AkkaParentProject(info: ProjectInfo) extends DefaultProject(info) { // Test // ------------------------------------------------------------------------------------------------------------------- - class AkkaActiveObjectTestProject(info: ProjectInfo) extends DefaultProject(info) { + class AkkaTypedActorTestProject(info: ProjectInfo) extends DefaultProject(info) { // testing val junit = "junit" % "junit" % "4.5" % "test" val jmock = "org.jmock" % "jmock" % "2.4.0" % "test"