diff --git a/akka-camel/src/test/scala/component/ActorComponentFeatureTest.scala b/akka-camel/src/test/scala/component/ActorComponentFeatureTest.scala index 58b2cdb169..e9a8a95a21 100644 --- a/akka-camel/src/test/scala/component/ActorComponentFeatureTest.scala +++ b/akka-camel/src/test/scala/component/ActorComponentFeatureTest.scala @@ -4,8 +4,8 @@ import org.apache.camel.RuntimeCamelException import org.scalatest.{BeforeAndAfterEach, BeforeAndAfterAll, FeatureSpec} import se.scalablesolutions.akka.actor.ActorRegistry -import se.scalablesolutions.akka.camel.CamelContextManager import se.scalablesolutions.akka.camel.support.{Respond, Countdown, Tester, Retain} +import se.scalablesolutions.akka.camel.{Message, CamelContextManager} class ActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with BeforeAndAfterEach { override protected def beforeAll() = { @@ -22,7 +22,7 @@ class ActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with import CamelContextManager.template scenario("one-way communication using actor id") { - val actor = new Tester with Retain with Countdown + val actor = new Tester with Retain with Countdown[Message] actor.start template.sendBody("actor:%s" format actor.getId, "Martin") assert(actor.waitFor) @@ -30,7 +30,7 @@ class ActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with } scenario("one-way communication using actor uuid") { - val actor = new Tester with Retain with Countdown + val actor = new Tester with Retain with Countdown[Message] actor.start template.sendBody("actor:uuid:%s" format actor.uuid, "Martin") assert(actor.waitFor) diff --git a/akka-camel/src/test/scala/component/ActorComponentTest.scala b/akka-camel/src/test/scala/component/ActorComponentTest.scala index 1f7b42bf08..6bf472916b 100644 --- a/akka-camel/src/test/scala/component/ActorComponentTest.scala +++ b/akka-camel/src/test/scala/component/ActorComponentTest.scala @@ -5,7 +5,6 @@ import org.junit._ import org.scalatest.junit.JUnitSuite class ActorComponentTest extends JUnitSuite { - val component: ActorComponent = ActorComponentTest.mockComponent @Test def shouldCreateEndpointWithIdDefined = { diff --git a/akka-camel/src/test/scala/component/ActorProducerTest.scala b/akka-camel/src/test/scala/component/ActorProducerTest.scala index afb4a12ef0..ad8d074f89 100644 --- a/akka-camel/src/test/scala/component/ActorProducerTest.scala +++ b/akka-camel/src/test/scala/component/ActorProducerTest.scala @@ -14,13 +14,10 @@ import se.scalablesolutions.akka.camel.support.{Countdown, Retain, Tester, Respo import se.scalablesolutions.akka.camel.{Failure, Message} class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { - - @After def tearDown = { - ActorRegistry.shutdownAll - } + @After def tearDown = ActorRegistry.shutdownAll @Test def shouldSendMessageToActor = { - val actor = new Tester with Retain with Countdown + val actor = new Tester with Retain with Countdown[Message] val endpoint = mockEndpoint("actor:uuid:%s" format actor.uuid) val exchange = endpoint.createExchange(ExchangePattern.InOnly) actor.start @@ -32,7 +29,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { assert(actor.headers === Map(Message.MessageExchangeId -> exchange.getExchangeId, "k1" -> "v1")) } - @Test def shouldSendMessageToActorAndReturnResponse = { + @Test def shouldSendMessageToActorAndReceiveResponse = { val actor = new Tester with Respond { override def response(msg: Message) = Message(super.response(msg), Map("k2" -> "v2")) } @@ -46,7 +43,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { assert(exchange.getOut.getHeader("k2") === "v2") } - @Test def shouldSendMessageToActorAndReturnFailure = { + @Test def shouldSendMessageToActorAndReceiveFailure = { val actor = new Tester with Respond { override def response(msg: Message) = Failure(new Exception("testmsg"), Map("k3" -> "v3")) } diff --git a/akka-camel/src/test/scala/service/CamelServiceFeatureTest.scala b/akka-camel/src/test/scala/service/CamelServiceFeatureTest.scala new file mode 100644 index 0000000000..de55c9001a --- /dev/null +++ b/akka-camel/src/test/scala/service/CamelServiceFeatureTest.scala @@ -0,0 +1,85 @@ +package se.scalablesolutions.akka.camel.service + +import org.apache.camel.builder.RouteBuilder +import org.scalatest.{GivenWhenThen, BeforeAndAfterAll, FeatureSpec} + +import se.scalablesolutions.akka.actor.{Actor, ActorRegistry} +import se.scalablesolutions.akka.camel.{CamelContextManager, Message, Consumer} + +class CamelServiceFeatureTest extends FeatureSpec with BeforeAndAfterAll with GivenWhenThen { + var service: CamelService = CamelService.newInstance + + override protected def beforeAll() = { + ActorRegistry.shutdownAll + // register test consumer before starting the CamelService + new TestConsumer("direct:publish-test-1").start + // Consigure a custom camel route + CamelContextManager.init + CamelContextManager.context.addRoutes(new TestRoute) + // set expectations for testing purposes + service.consumerPublisher.expectPublishCount(1) + // start the CamelService + service.load + // await publication of first test consumer + service.consumerPublisher.awaitPublish + } + + override protected def afterAll() = { + service.unload + ActorRegistry.shutdownAll + } + + feature("Publish registered consumer actors in the global CamelContext") { + + scenario("access registered consumer actors via Camel direct-endpoints") { + + given("two consumer actors registered before and after CamelService startup") + service.consumerPublisher.expectPublishCount(1) + new TestConsumer("direct:publish-test-2").start + + when("requests are sent to these actors") + service.consumerPublisher.awaitPublish + val response1 = CamelContextManager.template.requestBody("direct:publish-test-1", "msg1") + val response2 = CamelContextManager.template.requestBody("direct:publish-test-2", "msg2") + + then("both actors should have replied with expected responses") + assert(response1 === "received msg1") + assert(response2 === "received msg2") + } + } + + feature("Configure a custom Camel route for the global CamelContext") { + + scenario("access an actor from the custom Camel route") { + + given("a registered actor and a custom route to that actor") + val actor = new TestActor().start + + when("sending a a message to that route") + val response = CamelContextManager.template.requestBody("direct:custom-route-test-1", "msg3") + + then("an expected response generated by the actor should be returned") + assert(response === "received msg3") + } + } + + class TestConsumer(uri: String) extends Actor with Consumer { + def endpointUri = uri + protected def receive = { + case msg: Message => reply("received %s" format msg.body) + } + } + + class TestActor extends Actor { + id = "custom-actor-id" + protected def receive = { + case msg: Message => reply("received %s" format msg.body) + } + } + + class TestRoute extends RouteBuilder { + def configure { + from("direct:custom-route-test-1") .to("actor:custom-actor-id") + } + } +} \ No newline at end of file diff --git a/akka-camel/src/test/scala/service/CamelServiceTest.scala b/akka-camel/src/test/scala/service/CamelServiceTest.scala deleted file mode 100644 index a3b0f5c913..0000000000 --- a/akka-camel/src/test/scala/service/CamelServiceTest.scala +++ /dev/null @@ -1,103 +0,0 @@ -package se.scalablesolutions.akka.camel.service - -import org.apache.camel.builder.RouteBuilder -import org.junit.Assert._ -import org.scalatest.junit.JUnitSuite - -import se.scalablesolutions.akka.actor.Actor -import se.scalablesolutions.akka.actor.annotation.consume -import se.scalablesolutions.akka.camel.{CamelContextManager, Consumer, Message} -import org.junit.{Ignore, Before, After, Test} - -class CamelServiceTest extends JUnitSuite with CamelService { - - // - // TODO: extend/rewrite unit tests - // These tests currently only ensure proper functioning of basic features. - // - - import CamelContextManager._ - - var actor1: Actor = _ - var actor2: Actor = _ - var actor3: Actor = _ - - @Before def setUp = { - // register actors before starting the CamelService - actor1 = new TestActor1().start - actor2 = new TestActor2().start - actor3 = new TestActor3().start - // initialize global CamelContext - init - // customize global CamelContext - context.addRoutes(new TestRouteBuilder) - consumerPublisher.expectPublishCount(2) - load - consumerPublisher.awaitPublish - } - - @After def tearDown = { - unload - actor1.stop - actor2.stop - actor3.stop - } - - @Test def shouldReceiveResponseViaPreStartGeneratedRoutes = { - assertEquals("Hello Martin (actor1)", template.requestBody("direct:actor1", "Martin")) - assertEquals("Hello Martin (actor2)", template.requestBody("direct:actor2", "Martin")) - } - - @Test def shouldReceiveResponseViaPostStartGeneratedRoute = { - consumerPublisher.expectPublishCount(1) - // register actor after starting CamelService - val actor4 = new TestActor4().start - consumerPublisher.awaitPublish - assertEquals("Hello Martin (actor4)", template.requestBody("direct:actor4", "Martin")) - actor4.stop - } - - @Test def shouldReceiveResponseViaCustomRoute = { - assertEquals("Hello Tester (actor3)", template.requestBody("direct:actor3", "Martin")) - } - -} - -class TestActor1 extends Actor with Consumer { - def endpointUri = "direct:actor1" - - protected def receive = { - case msg: Message => reply("Hello %s (actor1)" format msg.body) - } -} - -@consume("direct:actor2") -class TestActor2 extends Actor { - protected def receive = { - case msg: Message => reply("Hello %s (actor2)" format msg.body) - } -} - -class TestActor3 extends Actor { - id = "actor3" - - protected def receive = { - case msg: Message => reply("Hello %s (actor3)" format msg.body) - } -} - -class TestActor4 extends Actor with Consumer { - def endpointUri = "direct:actor4" - - protected def receive = { - case msg: Message => reply("Hello %s (actor4)" format msg.body) - } -} - -class TestRouteBuilder extends RouteBuilder { - def configure { - val actorUri = "actor:%s" format classOf[TestActor3].getName - from("direct:actor3").transform(constant("Tester")).to("actor:actor3") - } -} - diff --git a/akka-camel/src/test/scala/service/PublishRequestorTest.scala b/akka-camel/src/test/scala/service/PublishRequestorTest.scala new file mode 100644 index 0000000000..d9b9b7bc61 --- /dev/null +++ b/akka-camel/src/test/scala/service/PublishRequestorTest.scala @@ -0,0 +1,36 @@ +package se.scalablesolutions.akka.camel.service + +import org.junit.{After, Test} +import org.scalatest.junit.JUnitSuite + +import se.scalablesolutions.akka.camel.Consumer +import se.scalablesolutions.akka.camel.support.{Receive, Countdown} +import se.scalablesolutions.akka.actor.{ActorRegistry, ActorRegistered, Actor} + +class PublishRequestorTest extends JUnitSuite { + @After def tearDown = ActorRegistry.shutdownAll + + @Test def shouldReceivePublishRequestOnActorRegisteredEvent = { + val consumer = new Actor with Consumer { + def endpointUri = "mock:test" + protected def receive = null + } + val publisher = new PublisherMock with Countdown[Publish] + val requestor = new PublishRequestor(publisher) + publisher.start + requestor.start + requestor.!(ActorRegistered(consumer))(None) + publisher.waitFor + assert(publisher.received === Publish("mock:test", consumer.uuid, true)) + publisher.stop + requestor.stop + } + + class PublisherMock extends Actor with Receive[Publish] { + var received: Publish = _ + protected def receive = { + case msg: Publish => onMessage(msg) + } + def onMessage(msg: Publish) = received = msg + } +} \ No newline at end of file diff --git a/akka-camel/src/test/scala/service/PublishTest.scala b/akka-camel/src/test/scala/service/PublishTest.scala new file mode 100644 index 0000000000..ffe5a3ad23 --- /dev/null +++ b/akka-camel/src/test/scala/service/PublishTest.scala @@ -0,0 +1,48 @@ +package se.scalablesolutions.akka.camel.service + +import org.junit.Test +import org.scalatest.junit.JUnitSuite + +import se.scalablesolutions.akka.actor.Actor +import se.scalablesolutions.akka.actor.annotation.consume +import se.scalablesolutions.akka.camel.Consumer + +class PublishTest extends JUnitSuite { + + @Test def shouldCreatePublishRequestList = { + val publish = Publish.forConsumers(List(new ConsumeAnnotatedActor)) + assert(publish === List(Publish("mock:test1", "test", false))) + } + + @Test def shouldCreateSomePublishRequestWithActorId = { + val publish = Publish.forConsumer(new ConsumeAnnotatedActor) + assert(publish === Some(Publish("mock:test1", "test", false))) + } + + @Test def shouldCreateSomePublishRequestWithActorUuid = { + val actor = new ConsumerActor + val publish = Publish.forConsumer(actor) + assert(publish === Some(Publish("mock:test2", actor.uuid, true))) + assert(publish === Some(Publish("mock:test2", actor.uuid, true))) + } + + @Test def shouldCreateNone = { + val publish = Publish.forConsumer(new PlainActor) + assert(publish === None) + } + + @consume("mock:test1") + class ConsumeAnnotatedActor extends Actor { + id = "test" + protected def receive = null + } + + class ConsumerActor extends Actor with Consumer { + def endpointUri = "mock:test2" + protected def receive = null + } + + class PlainActor extends Actor { + protected def receive = null + } +} \ No newline at end of file diff --git a/akka-camel/src/test/scala/support/TestSupport.scala b/akka-camel/src/test/scala/support/TestSupport.scala index f6b7998934..8dc7d4dd04 100644 --- a/akka-camel/src/test/scala/support/TestSupport.scala +++ b/akka-camel/src/test/scala/support/TestSupport.scala @@ -5,11 +5,11 @@ import java.util.concurrent.{TimeUnit, CountDownLatch} import se.scalablesolutions.akka.camel.Message import se.scalablesolutions.akka.actor.Actor -trait Receive { - def onMessage(msg: Message): Unit +trait Receive[T] { + def onMessage(msg: T): Unit } -trait Respond extends Receive {self: Actor => +trait Respond extends Receive[Message] {self: Actor => abstract override def onMessage(msg: Message): Unit = { super.onMessage(msg) reply(response(msg)) @@ -17,7 +17,7 @@ trait Respond extends Receive {self: Actor => def response(msg: Message): Any = "Hello %s" format msg.body } -trait Retain extends Receive { +trait Retain extends Receive[Message] { var body: Any = _ var headers = Map.empty[String, Any] abstract override def onMessage(msg: Message): Unit = { @@ -27,7 +27,7 @@ trait Retain extends Receive { } } -trait Countdown extends Receive { +trait Countdown[T] extends Receive[T] { val count = 1 val duration = 5000 val latch = new CountDownLatch(count) @@ -35,13 +35,13 @@ trait Countdown extends Receive { def waitFor = latch.await(duration, TimeUnit.MILLISECONDS) def countDown = latch.countDown - abstract override def onMessage(msg: Message) = { + abstract override def onMessage(msg: T) = { super.onMessage(msg) countDown } } -class Tester extends Actor with Receive { +class Tester extends Actor with Receive[Message] { def receive = { case msg: Message => onMessage(msg) }