Removed obsolete sample modules and cleaned up build file.
Signed-off-by: Jonas Bonér <jonas@jonasboner.com>
This commit is contained in:
parent
0a1740cd6d
commit
3640c09464
37 changed files with 11 additions and 1871 deletions
|
|
@ -1,46 +0,0 @@
|
|||
Ants
|
||||
====
|
||||
|
||||
Ants is written by Peter Vlugter.
|
||||
|
||||
Ants is roughly based on the Clojure [ants simulation][ants.clj] by Rich Hickey, and ported to Scala using [Akka][akka] and [Spde][spde].
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
To build and run Ants you need [Simple Build Tool][sbt] (sbt).
|
||||
|
||||
Running
|
||||
-------
|
||||
|
||||
First time, 'sbt update' to get dependencies, then to run Ants use 'sbt run'.
|
||||
Here is an example. First type 'sbt' to start SBT interactively, the run 'update' and 'run':
|
||||
> cd $AKKA_HOME
|
||||
|
||||
> % sbt
|
||||
|
||||
> > update
|
||||
|
||||
> > project akka-sample-ants
|
||||
|
||||
> > run
|
||||
|
||||
|
||||
Notice
|
||||
------
|
||||
|
||||
Ants is roughly based on the Clojure ants simulation by Rich Hickey.
|
||||
|
||||
Copyright (c) Rich Hickey. All rights reserved.
|
||||
The use and distribution terms for this software are covered by the
|
||||
Common Public License 1.0 ([http://opensource.org/licenses/cpl1.0.php][cpl])
|
||||
which can be found in the file cpl.txt at the root of this distribution.
|
||||
By using this software in any fashion, you are agreeing to be bound by
|
||||
the terms of this license.
|
||||
You must not remove this notice, or any other, from this software.
|
||||
|
||||
[ants.clj]:http://clojure.googlegroups.com/web/ants.clj
|
||||
[akka]:http://akkasource.org
|
||||
[spde]:http://technically.us/spde/
|
||||
[sbt]: http://code.google.com/p/simple-build-tool/
|
||||
[cpl]: http://opensource.org/licenses/cpl1.0.php
|
||||
|
|
@ -1,219 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package sample.ants
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scala.util.Random.{nextInt => randomInt}
|
||||
import akka.actor.{Actor, ActorRef, Scheduler}
|
||||
import akka.actor.Actor.actorOf
|
||||
import akka.stm._
|
||||
|
||||
object Config {
|
||||
val Dim = 80 // dimensions of square world
|
||||
val AntsSqrt = 20 // number of ants = AntsSqrt^2
|
||||
val FoodPlaces = 35 // number of places with food
|
||||
val FoodRange = 100 // range of amount of food at a place
|
||||
val PherScale = 10 // scale factor for pheromone drawing
|
||||
val AntMillis = 100 // how often an ant behaves (milliseconds)
|
||||
val EvapMillis = 1000 // how often pheromone evaporation occurs (milliseconds)
|
||||
val EvapRate = 0.99f // pheromone evaporation rate
|
||||
val StartDelay = 1000 // delay before everything kicks off (milliseconds)
|
||||
}
|
||||
|
||||
case class Ant(dir: Int, food: Boolean = false) {
|
||||
def turn(i: Int) = copy(dir = Util.dirBound(dir + i))
|
||||
def turnAround = turn(4)
|
||||
def pickUp = copy(food = true)
|
||||
def dropOff = copy(food = false)
|
||||
}
|
||||
|
||||
case class Cell(food: Int = 0, pher: Float = 0, ant: Option[Ant] = None, home: Boolean = false) {
|
||||
def addFood(i: Int) = copy(food = food + i)
|
||||
def addPher(x: Float) = copy(pher = pher + x)
|
||||
def alterPher(f: Float => Float) = copy(pher = f(pher))
|
||||
def putAnt(antOpt: Option[Ant]) = copy(ant = antOpt)
|
||||
def makeHome = copy(home = true)
|
||||
}
|
||||
|
||||
object EmptyCell extends Cell
|
||||
|
||||
class Place(initCell: Cell = EmptyCell) extends Ref(initCell) {
|
||||
def cell: Cell = getOrElse(EmptyCell)
|
||||
def food: Int = cell.food
|
||||
def food(i: Int) = alter(_.addFood(i))
|
||||
def hasFood = food > 0
|
||||
def pher: Float = cell.pher
|
||||
def pher(f: Float => Float) = alter(_.alterPher(f))
|
||||
def trail = alter(_.addPher(1))
|
||||
def ant: Option[Ant] = cell.ant
|
||||
def ant(f: Ant => Ant): Cell = alter(_.putAnt(ant map f))
|
||||
def enter(antOpt: Option[Ant]): Cell = alter(_.putAnt(antOpt))
|
||||
def enter(ant: Ant): Cell = enter(Some(ant))
|
||||
def leave = enter(None)
|
||||
def occupied: Boolean = ant.isDefined
|
||||
def makeHome = alter(_.makeHome)
|
||||
def home: Boolean = cell.home
|
||||
}
|
||||
|
||||
case object Ping
|
||||
|
||||
object World {
|
||||
import Config._
|
||||
|
||||
val homeOff = Dim / 4
|
||||
lazy val places = Vector.fill(Dim, Dim)(new Place)
|
||||
lazy val ants = setup
|
||||
lazy val evaporator = actorOf[Evaporator]
|
||||
|
||||
private val snapshotFactory = TransactionFactory(readonly = true, familyName = "snapshot")
|
||||
|
||||
def snapshot = atomic(snapshotFactory) { Array.tabulate(Dim, Dim)(place(_, _).opt) }
|
||||
|
||||
def place(loc: (Int, Int)) = places(loc._1)(loc._2)
|
||||
|
||||
private def setup = atomic {
|
||||
for (i <- 1 to FoodPlaces) {
|
||||
place(randomInt(Dim), randomInt(Dim)) food (randomInt(FoodRange))
|
||||
}
|
||||
val homeRange = homeOff until (AntsSqrt + homeOff)
|
||||
for (x <- homeRange; y <- homeRange) yield {
|
||||
place(x, y).makeHome
|
||||
place(x, y) enter Ant(randomInt(8))
|
||||
actorOf(new AntActor(x, y))
|
||||
}
|
||||
}
|
||||
|
||||
def start = {
|
||||
ants foreach pingEvery(AntMillis)
|
||||
pingEvery(EvapMillis)(evaporator)
|
||||
}
|
||||
|
||||
private def pingEvery(millis: Long)(actor: ActorRef) =
|
||||
Scheduler.schedule(actor, Ping, Config.StartDelay, millis, TimeUnit.MILLISECONDS)
|
||||
}
|
||||
|
||||
object Util {
|
||||
import Config._
|
||||
|
||||
def bound(b: Int, n: Int) = {
|
||||
val x = n % b
|
||||
if (x < 0) x + b else x
|
||||
}
|
||||
|
||||
def dirBound(n: Int) = bound(8, n)
|
||||
def dimBound(n: Int) = bound(Dim, n)
|
||||
|
||||
val dirDelta = Map(0 -> (0, -1), 1 -> (1, -1), 2 -> (1, 0), 3 -> (1, 1),
|
||||
4 -> (0, 1), 5 -> (-1, 1), 6 -> (-1, 0), 7 -> (-1, -1))
|
||||
def deltaLoc(x: Int, y: Int, dir: Int) = {
|
||||
val (dx, dy) = dirDelta(dirBound(dir))
|
||||
(dimBound(x + dx), dimBound(y + dy))
|
||||
}
|
||||
|
||||
def rankBy[A, B: Ordering](xs: Seq[A], f: A => B) = Map(xs.sortBy(f).zip(Stream from 1): _*)
|
||||
|
||||
def roulette(slices: Seq[Int]) = {
|
||||
val total = slices.sum
|
||||
val r = randomInt(total)
|
||||
var i, sum = 0
|
||||
while ((sum + slices(i)) <= r) {
|
||||
sum += slices(i)
|
||||
i += 1
|
||||
}
|
||||
i
|
||||
}
|
||||
}
|
||||
|
||||
trait WorldActor extends Actor {
|
||||
def act
|
||||
def receive = { case Ping => act }
|
||||
}
|
||||
|
||||
class AntActor(initLoc: (Int, Int)) extends WorldActor {
|
||||
import World._
|
||||
import Util._
|
||||
|
||||
val locRef = Ref(initLoc)
|
||||
|
||||
val name = "ant-from-" + initLoc._1 + "-" + initLoc._2
|
||||
implicit val txFactory = TransactionFactory(familyName = name)
|
||||
|
||||
val homing = (p: Place) => p.pher + (100 * (if (p.home) 0 else 1))
|
||||
val foraging = (p: Place) => p.pher + p.food
|
||||
|
||||
def loc = locRef.getOrElse(initLoc)
|
||||
def newLoc(l: (Int, Int)) = locRef swap l
|
||||
|
||||
def act = atomic {
|
||||
val (x, y) = loc
|
||||
val current = place(x, y)
|
||||
for (ant <- current.ant) {
|
||||
val ahead = place(deltaLoc(x, y, ant.dir))
|
||||
if (ant.food) { // homing
|
||||
if (current.home) dropFood
|
||||
else if (ahead.home && !ahead.occupied) move
|
||||
else random(homing)
|
||||
} else { // foraging
|
||||
if (!current.home && current.hasFood) pickUpFood
|
||||
else if (!ahead.home && ahead.hasFood && !ahead.occupied) move
|
||||
else random(foraging)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def move = {
|
||||
val (x, y) = loc
|
||||
val from = place(x, y)
|
||||
for (ant <- from.ant) {
|
||||
val toLoc = deltaLoc(x, y, ant.dir)
|
||||
val to = place(toLoc)
|
||||
to enter ant
|
||||
from.leave
|
||||
if (!from.home) from.trail
|
||||
newLoc(toLoc)
|
||||
}
|
||||
}
|
||||
|
||||
def pickUpFood = {
|
||||
val current = place(loc)
|
||||
current food -1
|
||||
current ant (_.pickUp.turnAround)
|
||||
}
|
||||
|
||||
def dropFood = {
|
||||
val current = place(loc)
|
||||
current food +1
|
||||
current ant (_.dropOff.turnAround)
|
||||
}
|
||||
|
||||
def random[A: Ordering](ranking: Place => A) = {
|
||||
val (x, y) = loc
|
||||
val current = place(x, y)
|
||||
for (ant <- current.ant) {
|
||||
val delta = (turn: Int) => place(deltaLoc(x, y, ant.dir + turn))
|
||||
val ahead = delta(0)
|
||||
val aheadLeft = delta(-1)
|
||||
val aheadRight = delta(+1)
|
||||
val locations = Seq(ahead, aheadLeft, aheadRight)
|
||||
val ranks = rankBy(locations, ranking)
|
||||
val ranked = Seq(ranks(aheadLeft), (if (ahead.occupied) 0 else ranks(ahead)), ranks(aheadRight))
|
||||
val dir = roulette(ranked) - 1
|
||||
if (dir == 0) move
|
||||
else current ant (_.turn(dir))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Evaporator extends WorldActor {
|
||||
import Config._
|
||||
import World._
|
||||
|
||||
implicit val txFactory = TransactionFactory(familyName = "evaporator")
|
||||
val evaporate = (pher: Float) => pher * EvapRate
|
||||
|
||||
def act = for (x <- 0 until Dim; y <- 0 until Dim) {
|
||||
atomic { place(x, y) pher evaporate }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import sample.ants._
|
||||
import sample.ants.Config._
|
||||
|
||||
val scale = 5
|
||||
|
||||
size(Dim * scale, Dim * scale)
|
||||
smooth()
|
||||
|
||||
override def setup() {
|
||||
background(255)
|
||||
World.start
|
||||
}
|
||||
|
||||
def draw() {
|
||||
val world = World.snapshot
|
||||
for (x <- 0 until Dim; y <- 0 until Dim; cell <- world(x)(y)) {
|
||||
val (rx, ry, rw, rh) = (x * scale, y * scale, scale, scale)
|
||||
noStroke()
|
||||
fill(255)
|
||||
rect(rx, ry, rw, rh)
|
||||
if (cell.pher > 0) fill(0, 255, 0, cell.pher * PherScale)
|
||||
if (cell.food > 0) fill(255, 0, 0, 255 * (cell.food / FoodRange.floatValue))
|
||||
rect(rx, ry, rw, rh)
|
||||
for (ant <- cell.ant) {
|
||||
if (ant.food) stroke(255, 0, 0) else stroke(0)
|
||||
val (hx, hy, tx, ty) = antLine(ant.dir)
|
||||
line(rx + hx, ry + hy, rx + tx, ry + ty)
|
||||
}
|
||||
stroke(0, 0, 255)
|
||||
noFill()
|
||||
val homeStart = World.homeOff * scale
|
||||
val homeWidth = AntsSqrt * scale
|
||||
rect(homeStart, homeStart, homeWidth, homeWidth)
|
||||
}
|
||||
}
|
||||
|
||||
val s = scale - 1
|
||||
val m = s / 2
|
||||
|
||||
def antLine(dir: Int) = dir match {
|
||||
case 0|4 => (m, 0, m, s)
|
||||
case 1|5 => (s, 0, 0, s)
|
||||
case 2|6 => (s, m, 0, m)
|
||||
case _ => (s, s, 0, 0)
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
####################
|
||||
# Akka Config File #
|
||||
####################
|
||||
|
||||
akka {
|
||||
version = "2.0-SNAPSHOT"
|
||||
|
||||
enabled-modules = ["camel", "http"]
|
||||
|
||||
time-unit = "seconds"
|
||||
|
||||
event-handlers = ["akka.event.EventHandler$DefaultListener"]
|
||||
|
||||
boot = ["sample.camel.Boot"]
|
||||
|
||||
http {
|
||||
hostname = "localhost"
|
||||
port = 9998
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Server Thread Pool -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="ThreadPool">
|
||||
<New class="org.eclipse.jetty.util.thread.ExecutorThreadPool">
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set connectors -->
|
||||
<!-- =========================================================== -->
|
||||
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
|
||||
<Set name="host"><SystemProperty name="jetty.host" /></Set>
|
||||
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
|
||||
<Set name="maxIdleTime">300000</Set>
|
||||
<Set name="Acceptors">2</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<Set name="confidentialPort">8443</Set>
|
||||
<Set name="lowResourcesConnections">20000</Set>
|
||||
<Set name="lowResourcesMaxIdleTime">5000</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set handler -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="handler">
|
||||
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
|
||||
<Set name="handlers">
|
||||
<Array type="org.eclipse.jetty.server.Handler">
|
||||
<Item>
|
||||
<New id="AkkaRestHandler" class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
<Set name="contextPath">/</Set>
|
||||
<Call name="addServlet">
|
||||
<Arg>akka.http.AkkaRestServlet</Arg>
|
||||
<Arg>/*</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- extra options -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="stopAtShutdown">true</Set>
|
||||
<Set name="sendServerVersion">true</Set>
|
||||
<Set name="sendDateHeader">true</Set>
|
||||
<Set name="gracefulShutdown">1000</Set>
|
||||
|
||||
</Configure>
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public class BeanImpl implements BeanIntf {
|
||||
|
||||
public String foo(String s) {
|
||||
return "hello " + s;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public interface BeanIntf {
|
||||
|
||||
public String foo(String s);
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import org.apache.camel.Body;
|
||||
import org.apache.camel.Header;
|
||||
|
||||
import akka.camel.consume;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public interface RemoteTypedConsumer1 {
|
||||
|
||||
@consume("jetty:http://localhost:6644/camel/remote-typed-actor-1")
|
||||
public String foo(@Body String body, @Header("name") String header);
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import akka.actor.TypedActor;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public class RemoteTypedConsumer1Impl implements RemoteTypedConsumer1 {
|
||||
|
||||
public String foo(String body, String header) {
|
||||
return String.format("remote1: body=%s header=%s", body, header);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import org.apache.camel.Body;
|
||||
import org.apache.camel.Header;
|
||||
import akka.camel.consume;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public interface RemoteTypedConsumer2 {
|
||||
|
||||
@consume("jetty:http://localhost:6644/camel/remote-typed-actor-2")
|
||||
public String foo(@Body String body, @Header("name") String header);
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public class RemoteTypedConsumer2Impl implements RemoteTypedConsumer2 {
|
||||
|
||||
public String foo(String body, String header) {
|
||||
return String.format("remote2: body=%s header=%s", body, header);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import org.apache.camel.Body;
|
||||
import org.apache.camel.Header;
|
||||
|
||||
import akka.camel.consume;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public interface TypedConsumer1 {
|
||||
@consume("file:data/input/typed-actor")
|
||||
public void foo(String body);
|
||||
|
||||
@consume("jetty:http://0.0.0.0:8877/camel/typed-actor")
|
||||
public String bar(@Body String body, @Header("name") String header);
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import org.apache.camel.Body;
|
||||
import org.apache.camel.Header;
|
||||
|
||||
import akka.actor.TypedActor;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public class TypedConsumer1Impl implements TypedConsumer1 {
|
||||
|
||||
public void foo(String body) {
|
||||
System.out.println("Received message:");
|
||||
System.out.println(body);
|
||||
}
|
||||
|
||||
public String bar(@Body String body, @Header("name") String header) {
|
||||
return String.format("body=%s header=%s", body, header);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import org.apache.camel.Body;
|
||||
import org.apache.camel.Header;
|
||||
import akka.camel.consume;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public interface TypedConsumer2 {
|
||||
|
||||
@consume("direct:default")
|
||||
public String foo(String body);
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public class TypedConsumer2Impl implements TypedConsumer2 {
|
||||
|
||||
public String foo(String body) {
|
||||
return String.format("default: %s", body);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import akka.camel.Message;
|
||||
import akka.camel.UntypedConsumerActor;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public class UntypedConsumer1 extends UntypedConsumerActor {
|
||||
|
||||
public String getEndpointUri() {
|
||||
return "direct:untyped-consumer-1";
|
||||
}
|
||||
|
||||
public void onReceive(Object message) {
|
||||
Message msg = (Message)message;
|
||||
String body = msg.getBodyAs(String.class);
|
||||
sender.tell(String.format("received %s", body));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- Camel JMS component and ActiveMQ setup -->
|
||||
<!-- ================================================================== -->
|
||||
|
||||
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
|
||||
<property name="configuration" ref="jmsConfig"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
|
||||
<property name="connectionFactory" ref="singleConnectionFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
|
||||
<property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
|
||||
<property name="brokerURL" value="vm://testbroker"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:akka="http://akka.io/schema/akka"
|
||||
xmlns:camel="http://camel.apache.org/schema/spring"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://akka.io/schema/akka
|
||||
http://akka.io/akka-2.0-SNAPSHOT.xsd
|
||||
http://camel.apache.org/schema/spring
|
||||
http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean id="routeBuilder" class="sample.camel.StandaloneSpringApplicationRoute" />
|
||||
|
||||
<camel:camelContext id="camelContext">
|
||||
<camel:routeBuilder ref="routeBuilder" />
|
||||
</camel:camelContext>
|
||||
|
||||
<akka:camel-service id="service">
|
||||
<akka:camel-context ref="camelContext" />
|
||||
</akka:camel-service>
|
||||
|
||||
<akka:typed-actor id="ta" interface="sample.camel.BeanIntf" implementation="sample.camel.BeanImpl" timeout="1000" />
|
||||
<akka:untyped-actor id="ua" implementation="sample.camel.UntypedConsumer1" scope="singleton" autostart="true" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
package sample.camel
|
||||
|
||||
import org.apache.camel.Exchange
|
||||
|
||||
import akka.actor.{ Actor, ActorRef, ActorRegistry }
|
||||
import akka.camel.{ Ack, Failure, Producer, Message, Consumer }
|
||||
|
||||
/**
|
||||
* Client-initiated remote actor.
|
||||
*/
|
||||
class RemoteActor1 extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://localhost:6644/camel/remote-actor-1"
|
||||
|
||||
protected def receive = {
|
||||
case msg: Message ⇒ sender ! Message("hello %s" format msg.bodyAs[String], Map("sender" -> "remote1"))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Server-initiated remote actor.
|
||||
*/
|
||||
class RemoteActor2 extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://localhost:6644/camel/remote-actor-2"
|
||||
|
||||
protected def receive = {
|
||||
case msg: Message ⇒ sender ! Message("hello %s" format msg.bodyAs[String], Map("sender" -> "remote2"))
|
||||
}
|
||||
}
|
||||
|
||||
class Producer1 extends Actor with Producer {
|
||||
def endpointUri = "direct:welcome"
|
||||
override def oneway = false // default
|
||||
}
|
||||
|
||||
class Consumer1 extends Actor with Consumer {
|
||||
def endpointUri = "file:data/input/actor"
|
||||
|
||||
def receive = {
|
||||
case msg: Message ⇒ println("received %s" format msg.bodyAs[String])
|
||||
}
|
||||
}
|
||||
|
||||
class Consumer2 extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8877/camel/default"
|
||||
|
||||
def receive = {
|
||||
case msg: Message ⇒ sender ! ("Hello %s" format msg.bodyAs[String])
|
||||
}
|
||||
}
|
||||
|
||||
class Consumer3(transformer: ActorRef) extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8877/camel/welcome"
|
||||
|
||||
def receive = {
|
||||
case msg: Message ⇒ transformer.forward(msg.setBodyAs[String])
|
||||
}
|
||||
}
|
||||
|
||||
class Consumer4 extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8877/camel/stop"
|
||||
|
||||
def receive = {
|
||||
case msg: Message ⇒ msg.bodyAs[String] match {
|
||||
case "stop" ⇒ {
|
||||
sender ! "Consumer4 stopped"
|
||||
self.stop
|
||||
}
|
||||
case body ⇒ sender ! body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Consumer5 extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8877/camel/start"
|
||||
|
||||
def receive = {
|
||||
case _ ⇒ {
|
||||
Actor.actorOf[Consumer4]
|
||||
sender ! "Consumer4 started"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Transformer(producer: ActorRef) extends Actor {
|
||||
protected def receive = {
|
||||
case msg: Message ⇒ producer.forward(msg.transformBody((body: String) ⇒ "- %s -" format body))
|
||||
}
|
||||
}
|
||||
|
||||
class Subscriber(name: String, uri: String) extends Actor with Consumer {
|
||||
def endpointUri = uri
|
||||
|
||||
protected def receive = {
|
||||
case msg: Message ⇒ println("%s received: %s" format (name, msg.body))
|
||||
}
|
||||
}
|
||||
|
||||
class Publisher(uri: String) extends Actor with Producer {
|
||||
def endpointUri = uri
|
||||
override def oneway = true
|
||||
}
|
||||
|
||||
class PublisherBridge(uri: String, publisher: ActorRef) extends Actor with Consumer {
|
||||
def endpointUri = uri
|
||||
|
||||
protected def receive = {
|
||||
case msg: Message ⇒ {
|
||||
publisher ! msg.bodyAs[String]
|
||||
sender ! "message published"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HttpConsumer(producer: ActorRef) extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8875/"
|
||||
|
||||
protected def receive = {
|
||||
case msg ⇒ producer forward msg
|
||||
}
|
||||
}
|
||||
|
||||
class HttpProducer(transformer: ActorRef) extends Actor with Producer {
|
||||
def endpointUri = "jetty://http://akka.io/?bridgeEndpoint=true"
|
||||
|
||||
override protected def receiveBeforeProduce = {
|
||||
// only keep Exchange.HTTP_PATH message header (which needed by bridge endpoint)
|
||||
case msg: Message ⇒ msg.setHeaders(msg.headers(Set(Exchange.HTTP_PATH)))
|
||||
}
|
||||
|
||||
override protected def receiveAfterProduce = {
|
||||
// do not reply but forward result to transformer
|
||||
case msg ⇒ transformer forward msg
|
||||
}
|
||||
}
|
||||
|
||||
class HttpTransformer extends Actor {
|
||||
protected def receive = {
|
||||
case msg: Message ⇒ sender ! (msg.transformBody { body: String ⇒ body replaceAll ("Akka ", "AKKA ") })
|
||||
case msg: Failure ⇒ sender ! msg
|
||||
}
|
||||
}
|
||||
|
||||
class FileConsumer extends Actor with Consumer {
|
||||
def endpointUri = "file:data/input/actor?delete=true"
|
||||
override def autoack = false
|
||||
|
||||
var counter = 0
|
||||
|
||||
def receive = {
|
||||
case msg: Message ⇒ {
|
||||
if (counter == 2) {
|
||||
println("received %s" format msg.bodyAs[String])
|
||||
sender ! Ack
|
||||
} else {
|
||||
println("rejected %s" format msg.bodyAs[String])
|
||||
counter += 1
|
||||
sender ! Failure(new Exception("message number %s not accepted" format counter))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
package sample.camel
|
||||
|
||||
import org.apache.camel.{ Exchange, Processor }
|
||||
import org.apache.camel.builder.RouteBuilder
|
||||
import org.apache.camel.impl.DefaultCamelContext
|
||||
import org.apache.camel.spring.spi.ApplicationContextRegistry
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext
|
||||
|
||||
import akka.actor.Actor._
|
||||
import akka.actor.Props
|
||||
import akka.actor.TypedActor
|
||||
import akka.camel.CamelContextManager
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
class Boot {
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Basic example
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
actorOf[Consumer1]
|
||||
actorOf[Consumer2]
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Custom Camel route example
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// Create CamelContext and a Spring-based registry
|
||||
val context = new ClassPathXmlApplicationContext("/context-jms.xml", getClass)
|
||||
val registry = new ApplicationContextRegistry(context)
|
||||
|
||||
// Use a custom Camel context and a custom touter builder
|
||||
CamelContextManager.init(new DefaultCamelContext(registry))
|
||||
CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder)
|
||||
|
||||
val producer = actorOf[Producer1]
|
||||
val mediator = actorOf(new Transformer(producer))
|
||||
val consumer = actorOf(new Consumer3(mediator))
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Asynchronous consumer-producer example (Akka homepage transformation)
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
val httpTransformer = actorOf(new HttpTransformer)
|
||||
val httpProducer = actorOf(new HttpProducer(httpTransformer))
|
||||
val httpConsumer = actorOf(new HttpConsumer(httpProducer))
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Publish subscribe examples
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Cometd example commented out because camel-cometd is broken since Camel 2.3
|
||||
//
|
||||
|
||||
//val cometdUri = "cometd://localhost:8111/test/abc?baseResource=file:target"
|
||||
//val cometdSubscriber = actorOf(new Subscriber("cometd-subscriber", cometdUri))
|
||||
//val cometdPublisher = actorOf(new Publisher("cometd-publisher", cometdUri))
|
||||
|
||||
val jmsUri = "jms:topic:test"
|
||||
val jmsSubscriber1 = actorOf(new Subscriber("jms-subscriber-1", jmsUri))
|
||||
val jmsSubscriber2 = actorOf(new Subscriber("jms-subscriber-2", jmsUri))
|
||||
val jmsPublisher = actorOf(new Publisher(jmsUri), "jms-publisher")
|
||||
|
||||
//val cometdPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/cometd", cometdPublisher))
|
||||
val jmsPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/jms", jmsPublisher))
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Actor un-publishing and re-publishing example
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
actorOf[Consumer4] // POSTing "stop" to http://0.0.0.0:8877/camel/stop stops and unpublishes this actor
|
||||
actorOf[Consumer5] // POSTing any msg to http://0.0.0.0:8877/camel/start starts and published Consumer4 again.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Active object example
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// TODO: investigate why this consumer is not published
|
||||
TypedActor.typedActorOf(classOf[TypedConsumer1], classOf[TypedConsumer1Impl], Props())
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
class CustomRouteBuilder extends RouteBuilder {
|
||||
def configure {
|
||||
val actorUri = "actor:%s" format classOf[Consumer2].getName
|
||||
from("jetty:http://0.0.0.0:8877/camel/custom").to(actorUri)
|
||||
from("direct:welcome").process(new Processor() {
|
||||
def process(exchange: Exchange) {
|
||||
exchange.getOut.setBody("Welcome %s" format exchange.getIn.getBody)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package sample.camel
|
||||
|
||||
import akka.actor.Actor._
|
||||
import akka.actor.TypedActor
|
||||
import akka.camel.Message
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
object ClientApplication extends App {
|
||||
|
||||
/* TODO: fix remote example
|
||||
|
||||
val actor1 = remote.actorOf[RemoteActor1]("localhost", 7777)
|
||||
val actor2 = remote.actorFor("remote2", "localhost", 7777)
|
||||
|
||||
val typedActor1 =
|
||||
TypedActor.newRemoteInstance(classOf[RemoteTypedConsumer1],classOf[RemoteTypedConsumer1Impl], "localhost", 7777)
|
||||
|
||||
val typedActor2 = remote.typedActorFor(classOf[RemoteTypedConsumer2], "remote3", "localhost", 7777)
|
||||
|
||||
println(actor1 !! Message("actor1")) // activates and publishes actor remotely
|
||||
println(actor2 !! Message("actor2")) // actor already activated and published remotely
|
||||
|
||||
println(typedActor1.foo("x1", "y1")) // activates and publishes typed actor methods remotely
|
||||
println(typedActor2.foo("x2", "y2")) // typed actor methods already activated and published remotely
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package sample.camel
|
||||
|
||||
import akka.actor.Actor._
|
||||
import akka.camel.CamelServiceManager
|
||||
import akka.actor.{ TypedActor, Props }
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
object ServerApplication extends App {
|
||||
import CamelServiceManager._
|
||||
|
||||
/* TODO: fix remote example
|
||||
|
||||
startCamelService
|
||||
|
||||
val ua = actorOf[RemoteActor2]
|
||||
val ta = TypedActor.typedActorOf(
|
||||
classOf[RemoteTypedConsumer2],
|
||||
classOf[RemoteTypedConsumer2Impl], Props())
|
||||
|
||||
remote.start("localhost", 7777)
|
||||
remote.register("remote2", ua)
|
||||
remote.registerTypedActor("remote3", ta)
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
package sample.camel
|
||||
|
||||
import org.apache.camel.impl.{ DefaultCamelContext, SimpleRegistry }
|
||||
import org.apache.camel.builder.RouteBuilder
|
||||
import org.apache.camel.spring.spi.ApplicationContextRegistry
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext
|
||||
|
||||
import akka.actor.{ Actor, TypedActor, Props }
|
||||
import akka.camel._
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
object StandaloneApplication extends App {
|
||||
import CamelContextManager._
|
||||
import CamelServiceManager._
|
||||
|
||||
// 'externally' register typed actors
|
||||
val registry = new SimpleRegistry
|
||||
registry.put("sample", TypedActor.typedActorOf(classOf[BeanIntf], classOf[BeanImpl], Props()))
|
||||
|
||||
// customize CamelContext
|
||||
CamelContextManager.init(new DefaultCamelContext(registry))
|
||||
CamelContextManager.mandatoryContext.addRoutes(new StandaloneApplicationRoute)
|
||||
|
||||
startCamelService
|
||||
|
||||
// access 'externally' registered typed actors
|
||||
assert("hello msg1" == mandatoryContext.createProducerTemplate.requestBody("direct:test", "msg1"))
|
||||
|
||||
mandatoryService.awaitEndpointActivation(1) {
|
||||
// 'internally' register typed actor (requires CamelService)
|
||||
TypedActor.typedActorOf(classOf[TypedConsumer2], classOf[TypedConsumer2Impl], Props())
|
||||
}
|
||||
|
||||
// access 'internally' (automatically) registered typed-actors
|
||||
// (see @consume annotation value at TypedConsumer2.foo method)
|
||||
assert("default: msg3" == mandatoryContext.createProducerTemplate.requestBody("direct:default", "msg3"))
|
||||
|
||||
stopCamelService
|
||||
|
||||
Actor.registry.local.shutdownAll
|
||||
}
|
||||
|
||||
class StandaloneApplicationRoute extends RouteBuilder {
|
||||
def configure = {
|
||||
// route to typed actors (in SimpleRegistry)
|
||||
from("direct:test").to("typed-actor:sample?method=foo")
|
||||
}
|
||||
}
|
||||
|
||||
object StandaloneSpringApplication extends App {
|
||||
import CamelContextManager._
|
||||
|
||||
// load Spring application context
|
||||
val appctx = new ClassPathXmlApplicationContext("/context-standalone.xml")
|
||||
|
||||
// We cannot use the CamelServiceManager to wait for endpoint activation
|
||||
// because CamelServiceManager is started by the Spring application context.
|
||||
// (and hence is not available for setting expectations on activations). This
|
||||
// will be improved/enabled in upcoming releases.
|
||||
Thread.sleep(1000)
|
||||
|
||||
// access 'externally' registered typed actors with typed-actor component
|
||||
assert("hello msg3" == mandatoryTemplate.requestBody("direct:test3", "msg3"))
|
||||
|
||||
// access auto-started untyped consumer
|
||||
assert("received msg3" == mandatoryTemplate.requestBody("direct:untyped-consumer-1", "msg3"))
|
||||
|
||||
appctx.close
|
||||
|
||||
Actor.registry.local.shutdownAll
|
||||
}
|
||||
|
||||
class StandaloneSpringApplicationRoute extends RouteBuilder {
|
||||
def configure = {
|
||||
// routes to typed actor (in ApplicationContextRegistry)
|
||||
from("direct:test3").to("typed-actor:ta?method=foo")
|
||||
}
|
||||
}
|
||||
|
||||
object StandaloneJmsApplication extends App {
|
||||
import CamelServiceManager._
|
||||
|
||||
val context = new ClassPathXmlApplicationContext("/context-jms.xml")
|
||||
val registry = new ApplicationContextRegistry(context)
|
||||
|
||||
// Init CamelContextManager with custom CamelContext
|
||||
CamelContextManager.init(new DefaultCamelContext(registry))
|
||||
|
||||
startCamelService
|
||||
|
||||
val jmsUri = "jms:topic:test"
|
||||
val jmsPublisher = Actor.actorOf(new Publisher(jmsUri), "jms-publisher")
|
||||
|
||||
mandatoryService.awaitEndpointActivation(2) {
|
||||
Actor.actorOf(new Subscriber("jms-subscriber-1", jmsUri))
|
||||
Actor.actorOf(new Subscriber("jms-subscriber-2", jmsUri))
|
||||
}
|
||||
|
||||
// Send 10 messages to via publisher actor
|
||||
for (i ← 1 to 10) {
|
||||
jmsPublisher ! ("Akka rocks (%d)" format i)
|
||||
}
|
||||
|
||||
// Send 10 messages to JMS topic directly
|
||||
for (i ← 1 to 10) {
|
||||
CamelContextManager.mandatoryTemplate.sendBody(jmsUri, "Camel rocks (%d)" format i)
|
||||
}
|
||||
|
||||
// Wait a bit for subscribes to receive messages
|
||||
Thread.sleep(1000)
|
||||
|
||||
stopCamelService
|
||||
Actor.registry.local.shutdownAll
|
||||
}
|
||||
|
||||
object StandaloneFileApplication {
|
||||
import CamelServiceManager._
|
||||
|
||||
def main(args: Array[String]) {
|
||||
startCamelService
|
||||
mandatoryService.awaitEndpointActivation(1) {
|
||||
Actor.actorOf(new FileConsumer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package sample.camel;
|
||||
|
||||
import akka.camel.Message;
|
||||
import akka.camel.UntypedConsumerActor;
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
public class SampleRemoteUntypedConsumer extends UntypedConsumerActor {
|
||||
public String getEndpointUri() {
|
||||
return "direct:remote-untyped-consumer";
|
||||
}
|
||||
|
||||
public void onReceive(Object message) {
|
||||
Message msg = (Message)message;
|
||||
String body = msg.getBodyAs(String.class);
|
||||
String header = msg.getHeaderAs("test", String.class);
|
||||
sender().tell(String.format("%s %s", body, header));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="false" debug="false">
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>[%4p] [%d{ISO8601}] [%t] %c{1}: %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="OFF">
|
||||
<appender-ref ref="stdout"/>
|
||||
</root>
|
||||
</configuration>
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
package sample.camel
|
||||
|
||||
import _root_.akka.routing.{ RoutedProps, Routing }
|
||||
import collection.mutable.Set
|
||||
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
import org.junit._
|
||||
import org.scalatest.junit.JUnitSuite
|
||||
|
||||
import akka.actor.Actor._
|
||||
import akka.actor.{ ActorRegistry, ActorRef, Actor }
|
||||
import akka.camel._
|
||||
import akka.camel.CamelServiceManager._
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
class HttpConcurrencyTestStress extends JUnitSuite {
|
||||
import HttpConcurrencyTestStress._
|
||||
|
||||
@Test
|
||||
def shouldProcessMessagesConcurrently = {
|
||||
/* TODO: fix stress test
|
||||
|
||||
val num = 50
|
||||
val latch1 = new CountDownLatch(num)
|
||||
val latch2 = new CountDownLatch(num)
|
||||
val latch3 = new CountDownLatch(num)
|
||||
val client1 = actorOf(new HttpClientActor("client1", latch1))
|
||||
val client2 = actorOf(new HttpClientActor("client2", latch2))
|
||||
val client3 = actorOf(new HttpClientActor("client3", latch3))
|
||||
for (i <- 1 to num) {
|
||||
client1 ! Message("client1", Map(Message.MessageExchangeId -> i))
|
||||
client2 ! Message("client2", Map(Message.MessageExchangeId -> i))
|
||||
client3 ! Message("client3", Map(Message.MessageExchangeId -> i))
|
||||
}
|
||||
latch1.await
|
||||
latch2.await
|
||||
latch3.await
|
||||
assert(num == (client1 ? "getCorrelationIdCount").as[Int].get)
|
||||
assert(num == (client2 ? "getCorrelationIdCount").as[Int].get)
|
||||
assert(num == (client3 ? "getCorrelationIdCount").as[Int].get)*/
|
||||
}
|
||||
}
|
||||
|
||||
object HttpConcurrencyTestStress {
|
||||
@BeforeClass
|
||||
def beforeClass{
|
||||
startCamelService
|
||||
|
||||
val workers = for (i ← 1 to 8) yield actorOf[HttpServerWorker]
|
||||
val balancer = Routing.actorOf(RoutedProps().withRoundRobinRouter.withConnections(workers), "loadbalancer")
|
||||
//service.get.awaitEndpointActivation(1) {
|
||||
// actorOf(new HttpServerActor(balancer))
|
||||
//}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
def afterClass = {
|
||||
stopCamelService
|
||||
Actor.registry.local.shutdownAll
|
||||
}
|
||||
|
||||
class HttpClientActor(label: String, latch: CountDownLatch) extends Actor with Producer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8855/echo"
|
||||
var correlationIds = Set[Any]()
|
||||
|
||||
override protected def receive = {
|
||||
case "getCorrelationIdCount" ⇒ sender ! correlationIds.size
|
||||
case msg ⇒ super.receive(msg)
|
||||
}
|
||||
|
||||
override protected def receiveAfterProduce = {
|
||||
case msg: Message ⇒ {
|
||||
val corr = msg.headers(Message.MessageExchangeId)
|
||||
val body = msg.bodyAs[String]
|
||||
correlationIds += corr
|
||||
assert(label == body)
|
||||
latch.countDown
|
||||
print(".")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HttpServerActor(balancer: ActorRef) extends Actor with Consumer {
|
||||
def endpointUri = "jetty:http://0.0.0.0:8855/echo"
|
||||
var counter = 0
|
||||
|
||||
def receive = {
|
||||
case msg ⇒ balancer forward msg
|
||||
}
|
||||
}
|
||||
|
||||
class HttpServerWorker extends Actor {
|
||||
protected def receive = {
|
||||
case msg ⇒ sender ! msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
package sample.camel
|
||||
|
||||
import org.scalatest.{ GivenWhenThen, BeforeAndAfterAll, FeatureSpec }
|
||||
|
||||
import akka.actor.Actor._
|
||||
import akka.actor._
|
||||
import akka.camel._
|
||||
//import akka.cluster.netty.NettyRemoteSupport
|
||||
//import akka.cluster.RemoteServerModule
|
||||
|
||||
/**
|
||||
* @author Martin Krasser
|
||||
*/
|
||||
class RemoteConsumerTest /*extends FeatureSpec with BeforeAndAfterAll with GivenWhenThen*/ {
|
||||
/* TODO: fix remote test
|
||||
|
||||
import CamelServiceManager._
|
||||
import RemoteConsumerTest._
|
||||
|
||||
var server: RemoteServerModule = _
|
||||
|
||||
override protected def beforeAll = {
|
||||
registry.shutdownAll
|
||||
|
||||
startCamelService
|
||||
|
||||
remote.shutdown
|
||||
remote.asInstanceOf[NettyRemoteSupport].optimizeLocal.set(false)
|
||||
|
||||
server = remote.start(host,port)
|
||||
}
|
||||
|
||||
override protected def afterAll = {
|
||||
remote.shutdown
|
||||
|
||||
stopCamelService
|
||||
|
||||
registry.shutdownAll
|
||||
remote.asInstanceOf[NettyRemoteSupport].optimizeLocal.set(true)
|
||||
}
|
||||
|
||||
feature("Publish consumer on remote node") {
|
||||
scenario("access published remote consumer") {
|
||||
given("a consumer actor")
|
||||
val consumer = Actor.actorOf[RemoteConsumer]
|
||||
|
||||
when("registered at the server")
|
||||
assert(mandatoryService.awaitEndpointActivation(1) {
|
||||
remote.register(consumer)
|
||||
})
|
||||
|
||||
then("the published consumer is accessible via its endpoint URI")
|
||||
val response = CamelContextManager.mandatoryTemplate.requestBody("direct:remote-consumer", "test")
|
||||
assert(response === "remote actor: test")
|
||||
}
|
||||
}
|
||||
|
||||
feature("Publish typed consumer on remote node") {
|
||||
scenario("access published remote consumer method") {
|
||||
given("a typed consumer actor")
|
||||
when("registered at the server")
|
||||
assert(mandatoryService.awaitEndpointActivation(1) {
|
||||
remote.registerTypedActor("whatever", TypedActor.newInstance(
|
||||
classOf[SampleRemoteTypedConsumer],
|
||||
classOf[SampleRemoteTypedConsumerImpl]))
|
||||
})
|
||||
then("the published method is accessible via its endpoint URI")
|
||||
val response = CamelContextManager.mandatoryTemplate.requestBody("direct:remote-typed-consumer", "test")
|
||||
assert(response === "remote typed actor: test")
|
||||
}
|
||||
}
|
||||
|
||||
feature("Publish untyped consumer on remote node") {
|
||||
scenario("access published remote untyped consumer") {
|
||||
given("an untyped consumer actor")
|
||||
val consumer = Actor.actorOf(classOf[SampleRemoteUntypedConsumer])
|
||||
|
||||
when("registered at the server")
|
||||
assert(mandatoryService.awaitEndpointActivation(1) {
|
||||
remote.register(consumer)
|
||||
})
|
||||
then("the published untyped consumer is accessible via its endpoint URI")
|
||||
val response = CamelContextManager.mandatoryTemplate.requestBodyAndHeader("direct:remote-untyped-consumer", "a", "test", "b")
|
||||
assert(response === "a b")
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
object RemoteConsumerTest {
|
||||
val host = "localhost"
|
||||
val port = 7774
|
||||
|
||||
class RemoteConsumer extends Actor with Consumer {
|
||||
def endpointUri = "direct:remote-consumer"
|
||||
|
||||
protected def receive = {
|
||||
case "init" ⇒ sender ! "done"
|
||||
case m: Message ⇒ sender ! ("remote actor: %s" format m.body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
Akka Chat Client/Server Sample Application
|
||||
|
||||
How to run the sample:
|
||||
|
||||
1. Fire up two shells. For each of them:
|
||||
- Step down into to the root of the Akka distribution.
|
||||
- Set 'export AKKA_HOME=<root of distribution>.
|
||||
- Run 'sbt console' to start up a REPL (interpreter).
|
||||
2. In the first REPL you get execute:
|
||||
- scala> import sample.chat._
|
||||
- scala> import akka.actor.Actor._
|
||||
- scala> val chatService = actorOf[ChatService]
|
||||
3. In the second REPL you get execute:
|
||||
- scala> import sample.chat._
|
||||
- scala> ClientRunner.run
|
||||
4. See the chat simulation run.
|
||||
5. Run it again to see full speed after first initialization.
|
||||
6. In the client REPL, or in a new REPL, you can also create your own client
|
||||
- scala> import sample.chat._
|
||||
- scala> val myClient = new ChatClient("<your name>")
|
||||
- scala> myClient.login
|
||||
- scala> myClient.post("Can I join?")
|
||||
- scala> println("CHAT LOG:\n\t" + myClient.chatLog.log.mkString("\n\t"))
|
||||
|
||||
That’s it. Have fun.
|
||||
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2010 Typesafe Inc. <http://www.typesafe.com>.
|
||||
*/
|
||||
|
||||
package sample.chat
|
||||
|
||||
import scala.collection.mutable.HashMap
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Props}
|
||||
import akka.stm._
|
||||
import akka.actor.Actor._
|
||||
import akka.event.EventHandler
|
||||
|
||||
/******************************************************************************
|
||||
Akka Chat Client/Server Sample Application
|
||||
|
||||
How to run the sample:
|
||||
|
||||
1. Fire up two shells. For each of them:
|
||||
- Step down into to the root of the Akka distribution.
|
||||
- Set 'export AKKA_HOME=<root of distribution>.
|
||||
- Run 'sbt console' to start up a REPL (interpreter).
|
||||
2. In the first REPL you get execute:
|
||||
- scala> import sample.chat._
|
||||
- scala> import akka.actor.Actor._
|
||||
- scala> val chatService = actorOf[ChatService]
|
||||
3. In the second REPL you get execute:
|
||||
- scala> import sample.chat._
|
||||
- scala> ClientRunner.run
|
||||
4. See the chat simulation run.
|
||||
5. Run it again to see full speed after first initialization.
|
||||
6. In the client REPL, or in a new REPL, you can also create your own client
|
||||
- scala> import sample.chat._
|
||||
- scala> val myClient = new ChatClient("<your name>")
|
||||
- scala> myClient.login
|
||||
- scala> myClient.post("Can I join?")
|
||||
- scala> println("CHAT LOG:\n\t" + myClient.chatLog.log.mkString("\n\t"))
|
||||
|
||||
|
||||
That’s it. Have fun.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* ChatServer's internal events.
|
||||
*/
|
||||
sealed trait Event
|
||||
case class Login(user: String) extends Event
|
||||
case class Logout(user: String) extends Event
|
||||
case class GetChatLog(from: String) extends Event
|
||||
case class ChatLog(log: List[String]) extends Event
|
||||
case class ChatMessage(from: String, message: String) extends Event
|
||||
|
||||
/**
|
||||
* Chat client.
|
||||
*/
|
||||
class ChatClient(val name: String) {
|
||||
val chat = Actor.remote.actorFor("chat:service", "localhost", 2552)
|
||||
|
||||
def login = chat ! Login(name)
|
||||
def logout = chat ! Logout(name)
|
||||
def post(message: String) = chat ! ChatMessage(name, name + ": " + message)
|
||||
def chatLog = (chat !! GetChatLog(name)).as[ChatLog].getOrElse(throw new Exception("Couldn't get the chat log from ChatServer"))
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal chat client session.
|
||||
*/
|
||||
class Session(user: String, storage: ActorRef) extends Actor {
|
||||
private val loginTime = System.currentTimeMillis
|
||||
private var userLog: List[String] = Nil
|
||||
|
||||
EventHandler.info(this, "New session for user [%s] has been created at [%s]".format(user, loginTime))
|
||||
|
||||
def receive = {
|
||||
case msg @ ChatMessage(from, message) =>
|
||||
userLog ::= message
|
||||
storage ! msg
|
||||
|
||||
case msg @ GetChatLog(_) =>
|
||||
storage forward msg
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstraction of chat storage holding the chat log.
|
||||
*/
|
||||
trait ChatStorage extends Actor
|
||||
|
||||
/**
|
||||
* Memory-backed chat storage implementation.
|
||||
*/
|
||||
class MemoryChatStorage extends ChatStorage {
|
||||
private var chatLog = TransactionalVector[Array[Byte]]()
|
||||
|
||||
EventHandler.info(this, "Memory-based chat storage is starting up...")
|
||||
|
||||
def receive = {
|
||||
case msg @ ChatMessage(from, message) =>
|
||||
EventHandler.debug(this, "New chat message [%s]".format(message))
|
||||
atomic { chatLog + message.getBytes("UTF-8") }
|
||||
|
||||
case GetChatLog(_) =>
|
||||
val messageList = atomic { chatLog.map(bytes => new String(bytes, "UTF-8")).toList }
|
||||
reply(ChatLog(messageList))
|
||||
}
|
||||
|
||||
override def postRestart(reason: Throwable) {
|
||||
chatLog = TransactionalVector()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements user session management.
|
||||
* <p/>
|
||||
* Uses self-type annotation (this: Actor =>) to declare that it needs to be mixed in with an Actor.
|
||||
*/
|
||||
trait SessionManagement { this: Actor =>
|
||||
|
||||
val storage: ActorRef // needs someone to provide the ChatStorage
|
||||
val sessions = new HashMap[String, ActorRef]
|
||||
|
||||
protected def sessionManagement: Receive = {
|
||||
case Login(username) =>
|
||||
EventHandler.info(this, "User [%s] has logged in".format(username))
|
||||
val session = actorOf(new Session(username, storage))
|
||||
session
|
||||
sessions += (username -> session)
|
||||
|
||||
case Logout(username) =>
|
||||
EventHandler.info(this, "User [%s] has logged out".format(username))
|
||||
val session = sessions(username)
|
||||
session.stop()
|
||||
sessions -= username
|
||||
}
|
||||
|
||||
protected def shutdownSessions() {
|
||||
sessions.foreach { case (_, session) => session.stop() }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements chat management, e.g. chat message dispatch.
|
||||
* <p/>
|
||||
* Uses self-type annotation (this: Actor =>) to declare that it needs to be mixed in with an Actor.
|
||||
*/
|
||||
trait ChatManagement { this: Actor =>
|
||||
val sessions: HashMap[String, ActorRef] // needs someone to provide the Session map
|
||||
|
||||
protected def chatManagement: Receive = {
|
||||
case msg @ ChatMessage(from, _) => getSession(from).foreach(_ ! msg)
|
||||
case msg @ GetChatLog(from) => getSession(from).foreach(_ forward msg)
|
||||
}
|
||||
|
||||
private def getSession(from: String) : Option[ActorRef] = {
|
||||
if (sessions.contains(from))
|
||||
Some(sessions(from))
|
||||
else {
|
||||
EventHandler.info(this, "Session expired for %s".format(from))
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and links a MemoryChatStorage.
|
||||
*/
|
||||
trait MemoryChatStorageFactory { this: Actor =>
|
||||
val storage = actorOf(Props[MemoryChatStorage].withSupervisor(this.self)) // starts and links ChatStorage
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat server. Manages sessions and redirects all other messages to the Session for the client.
|
||||
*/
|
||||
trait ChatServer extends Actor {
|
||||
//faultHandler = OneForOneStrategy(List(classOf[Exception]),5, 5000)
|
||||
val storage: ActorRef
|
||||
|
||||
EventHandler.info(this, "Chat server is starting up...")
|
||||
|
||||
// actor message handler
|
||||
def receive: Receive = sessionManagement orElse chatManagement
|
||||
|
||||
// abstract methods to be defined somewhere else
|
||||
protected def chatManagement: Receive
|
||||
protected def sessionManagement: Receive
|
||||
protected def shutdownSessions()
|
||||
|
||||
override def postStop() {
|
||||
EventHandler.info(this, "Chat server is shutting down...")
|
||||
shutdownSessions()
|
||||
storage.stop()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class encapsulating the full Chat Service.
|
||||
* Start service by invoking:
|
||||
* <pre>
|
||||
* val chatService = Actor.actorOf[ChatService]
|
||||
* </pre>
|
||||
*/
|
||||
class ChatService extends
|
||||
ChatServer with
|
||||
SessionManagement with
|
||||
ChatManagement with
|
||||
MemoryChatStorageFactory {
|
||||
override def preStart() {
|
||||
remote.start("localhost", 2552);
|
||||
remote.register("chat:service", self) //Register the actor with the specified service id
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test runner starting ChatService.
|
||||
*/
|
||||
object ServerRunner {
|
||||
|
||||
def main(args: Array[String]) { ServerRunner.run() }
|
||||
|
||||
def run() {
|
||||
actorOf[ChatService]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test runner emulating a chat session.
|
||||
*/
|
||||
object ClientRunner {
|
||||
|
||||
def main(args: Array[String]) { ClientRunner.run() }
|
||||
|
||||
def run() {
|
||||
|
||||
val client1 = new ChatClient("jonas")
|
||||
client1.login
|
||||
val client2 = new ChatClient("patrik")
|
||||
client2.login
|
||||
|
||||
client1.post("Hi there")
|
||||
println("CHAT LOG:\n\t" + client1.chatLog.log.mkString("\n\t"))
|
||||
|
||||
client2.post("Hello")
|
||||
println("CHAT LOG:\n\t" + client2.chatLog.log.mkString("\n\t"))
|
||||
|
||||
client1.post("Hi again")
|
||||
println("CHAT LOG:\n\t" + client1.chatLog.log.mkString("\n\t"))
|
||||
|
||||
client1.logout
|
||||
client2.logout
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
####################
|
||||
# Akka Config File #
|
||||
####################
|
||||
|
||||
akka {
|
||||
version = "2.0-SNAPSHOT"
|
||||
|
||||
enabled-modules = ["http"]
|
||||
|
||||
time-unit = "seconds"
|
||||
|
||||
event-handlers = ["akka.event.EventHandler$DefaultListener"]
|
||||
|
||||
boot = ["sample.hello.Boot"]
|
||||
|
||||
http {
|
||||
hostname = "localhost"
|
||||
port = 9998
|
||||
|
||||
connection-close = true
|
||||
root-actor-id = "_httproot"
|
||||
root-actor-builtin = true
|
||||
timeout = 1000
|
||||
expired-header-name = "Async-Timeout"
|
||||
expired-header-value = "expired"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Server Thread Pool -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="ThreadPool">
|
||||
<New class="org.eclipse.jetty.util.thread.ExecutorThreadPool">
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set connectors -->
|
||||
<!-- =========================================================== -->
|
||||
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
|
||||
<Set name="host"><SystemProperty name="jetty.host" /></Set>
|
||||
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
|
||||
<Set name="maxIdleTime">300000</Set>
|
||||
<Set name="Acceptors">2</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<Set name="confidentialPort">8443</Set>
|
||||
<Set name="lowResourcesConnections">20000</Set>
|
||||
<Set name="lowResourcesMaxIdleTime">5000</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set handler -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="handler">
|
||||
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
|
||||
<Set name="handlers">
|
||||
<Array type="org.eclipse.jetty.server.Handler">
|
||||
<Item>
|
||||
<New id="AkkaMistHandler" class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
<Set name="contextPath">/</Set>
|
||||
<Call name="addServlet">
|
||||
<Arg>akka.http.AkkaMistServlet</Arg>
|
||||
<Arg>/*</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Extra options -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="stopAtShutdown">true</Set>
|
||||
<Set name="sendServerVersion">true</Set>
|
||||
<Set name="sendDateHeader">true</Set>
|
||||
<Set name="gracefulShutdown">1000</Set>
|
||||
|
||||
</Configure>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package sample.hello
|
||||
|
||||
import akka.actor._
|
||||
import akka.http._
|
||||
|
||||
class Boot {
|
||||
val supervisor = Supervisor(OneForOneStrategy(List(classOf[Exception]), 3, 100))
|
||||
Actor.actorOf(Props[RootEndpoint].withSupervisor(supervisor))
|
||||
Actor.actorOf(Props[HelloEndpoint].withSupervisor(supervisor))
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package sample.hello
|
||||
|
||||
import akka.actor._
|
||||
import akka.http._
|
||||
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
|
||||
class HelloEndpoint extends Actor with Endpoint {
|
||||
self.dispatcher = Endpoint.Dispatcher
|
||||
|
||||
lazy val hello = Actor.actorOf(
|
||||
new Actor {
|
||||
def time = DateFormat.getTimeInstance.format(new Date)
|
||||
def receive = {
|
||||
case get: Get => get OK "Hello at " + time
|
||||
}
|
||||
})
|
||||
|
||||
def hook: Endpoint.Hook = { case _ => hello }
|
||||
|
||||
override def preStart = Actor.registry.actorFor(MistSettings.RootActorID).get ! Endpoint.Attach(hook)
|
||||
|
||||
def receive = handleHttpRequest
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package sample.osgi
|
||||
|
||||
import akka.actor.Actor
|
||||
import akka.actor.Actor._
|
||||
|
||||
import org.osgi.framework.{ BundleActivator, BundleContext }
|
||||
|
||||
class Activator extends BundleActivator {
|
||||
|
||||
def start(context: BundleContext) {
|
||||
println("Starting the OSGi example ...")
|
||||
val echo = actorOf[EchoActor]
|
||||
val answer = (echo ? "OSGi example").as[String]
|
||||
println(answer getOrElse "No answer!")
|
||||
}
|
||||
|
||||
def stop(context: BundleContext) {
|
||||
Actor.registry.local.shutdownAll()
|
||||
println("Stopped the OSGi example.")
|
||||
}
|
||||
}
|
||||
|
||||
class EchoActor extends Actor {
|
||||
|
||||
override def receive = {
|
||||
case x => reply(x)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
---------------------------------------------------------
|
||||
== Akka Remote Sample Application ==
|
||||
---------------------------------------------------------
|
||||
= Server Managed Remote Actors Sample =
|
||||
|
||||
To run the sample:
|
||||
|
||||
1. Fire up two shells. For each of them:
|
||||
- Step down into to the root of the Akka distribution.
|
||||
- Set 'export AKKA_HOME=<root of distribution>.
|
||||
- Run 'sbt'
|
||||
- Run 'update' followed by 'compile' if you have not done that before.
|
||||
- Run 'project akka-sample-remote'
|
||||
- Run 'console' to start up a REPL (interpreter).
|
||||
2. In the first REPL you get execute:
|
||||
- scala> import sample.remote._
|
||||
- scala> ServerManagedRemoteActorServer.run
|
||||
This starts up the RemoteNode and registers the remote actor
|
||||
3. In the second REPL you get execute:
|
||||
- scala> import sample.remote._
|
||||
- scala> ServerManagedRemoteActorClient.run
|
||||
4. See the actor conversation.
|
||||
5. Run it again to see full speed after first initialization.
|
||||
|
||||
Now you could test client reconnect by killing the console running the ServerManagedRemoteActorClient and start it up again. See the client reconnect take place in the REPL shell.
|
||||
|
||||
That’s it. Have fun.
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package sample.remote
|
||||
|
||||
import akka.actor.Actor._
|
||||
import akka.actor. {ActorRegistry, Actor}
|
||||
|
||||
class HelloWorldActor extends Actor {
|
||||
def receive = {
|
||||
case "Hello" =>
|
||||
reply("World")
|
||||
}
|
||||
}
|
||||
|
||||
object ServerManagedRemoteActorServer {
|
||||
|
||||
def run = {
|
||||
Actor.remote.start("localhost", 2552)
|
||||
Actor.remote.register("hello-service", actorOf[HelloWorldActor])
|
||||
}
|
||||
|
||||
def main(args: Array[String]) = run
|
||||
}
|
||||
|
||||
object ServerManagedRemoteActorClient {
|
||||
|
||||
def run = {
|
||||
val actor = Actor.remote.actorFor("hello-service", "localhost", 2552)
|
||||
val result = actor !! "Hello"
|
||||
}
|
||||
|
||||
def main(args: Array[String]) = run
|
||||
}
|
||||
|
||||
|
|
@ -1,11 +1,18 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka
|
||||
|
||||
import sbt._
|
||||
import Keys._
|
||||
|
||||
import com.typesafe.sbtmultijvm.MultiJvmPlugin
|
||||
import MultiJvmPlugin.{ MultiJvm, extraOptions, jvmOptions, scalatestOptions }
|
||||
import com.typesafe.sbtscalariform.ScalariformPlugin
|
||||
|
||||
import MultiJvmPlugin.{ MultiJvm, extraOptions, jvmOptions, scalatestOptions }
|
||||
import ScalariformPlugin.{ format, formatPreferences, formatSourceDirectories }
|
||||
|
||||
import java.lang.Boolean.getBoolean
|
||||
|
||||
object AkkaBuild extends Build {
|
||||
|
|
@ -26,7 +33,6 @@ object AkkaBuild extends Build {
|
|||
rstdocDirectory <<= baseDirectory / "akka-docs"
|
||||
),
|
||||
aggregate = Seq(actor, testkit, actorTests, stm, remote, slf4j, amqp, mailboxes, akkaSbtPlugin, samples, tutorials, docs)
|
||||
//aggregate = Seq(cluster, mailboxes, camel, camelTyped)
|
||||
)
|
||||
|
||||
lazy val actor = Project(
|
||||
|
|
@ -88,23 +94,6 @@ object AkkaBuild extends Build {
|
|||
)
|
||||
) configs (MultiJvm)
|
||||
|
||||
// lazy val cluster = Project(
|
||||
// id = "akka-cluster",
|
||||
// base = file("akka-cluster"),
|
||||
// dependencies = Seq(stm, actorTests % "test->test", testkit % "test"),
|
||||
// settings = defaultSettings ++ multiJvmSettings ++ Seq(
|
||||
// libraryDependencies ++= Dependencies.cluster,
|
||||
// extraOptions in MultiJvm <<= (sourceDirectory in MultiJvm) { src =>
|
||||
// (name: String) => (src ** (name + ".conf")).get.headOption.map("-Dakka.config=" + _.absolutePath).toSeq
|
||||
// },
|
||||
// scalatestOptions in MultiJvm := Seq("-r", "org.scalatest.akka.QuietReporter"),
|
||||
// jvmOptions in MultiJvm := {
|
||||
// if (getBoolean("sbt.log.noformat")) Seq("-Dakka.test.nocolor=true") else Nil
|
||||
// },
|
||||
// test in Test <<= (test in Test) dependsOn (test in MultiJvm)
|
||||
// )
|
||||
// ) configs (MultiJvm)
|
||||
|
||||
lazy val slf4j = Project(
|
||||
id = "akka-slf4j",
|
||||
base = file("akka-slf4j"),
|
||||
|
|
@ -173,7 +162,7 @@ object AkkaBuild extends Build {
|
|||
testOptions in Test <+= testRedisMailbox map { test => Tests.Filter(s => test) }
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
lazy val zookeeperMailbox = Project(
|
||||
id = "akka-zookeeper-mailbox",
|
||||
base = file("akka-durable-mailboxes/akka-zookeeper-mailbox"),
|
||||
|
|
@ -196,23 +185,6 @@ object AkkaBuild extends Build {
|
|||
)
|
||||
)
|
||||
|
||||
// lazy val camel = Project(
|
||||
// id = "akka-camel",
|
||||
// base = file("akka-camel"),
|
||||
// dependencies = Seq(actor, slf4j, testkit % "test"),
|
||||
// settings = defaultSettings ++ Seq(
|
||||
// libraryDependencies ++= Dependencies.camel
|
||||
// )
|
||||
// )
|
||||
|
||||
// can be merged back into akka-camel
|
||||
// lazy val camelTyped = Project(
|
||||
// id = "akka-camel-typed",
|
||||
// base = file("akka-camel-typed"),
|
||||
// dependencies = Seq(camel % "compile;test->test", testkit % "test"),
|
||||
// settings = defaultSettings
|
||||
// )
|
||||
|
||||
// lazy val spring = Project(
|
||||
// id = "akka-spring",
|
||||
// base = file("akka-spring"),
|
||||
|
|
@ -244,23 +216,8 @@ object AkkaBuild extends Build {
|
|||
base = file("akka-samples"),
|
||||
settings = parentSettings,
|
||||
aggregate = Seq(fsmSample)
|
||||
// aggregate = Seq(fsmSample, camelSample)
|
||||
)
|
||||
|
||||
// lazy val antsSample = Project(
|
||||
// id = "akka-sample-ants",
|
||||
// base = file("akka-samples/akka-sample-ants"),
|
||||
// dependencies = Seq(stm),
|
||||
// settings = defaultSettings
|
||||
// )
|
||||
|
||||
// lazy val chatSample = Project(
|
||||
// id = "akka-sample-chat",
|
||||
// base = file("akka-samples/akka-sample-chat"),
|
||||
// dependencies = Seq(cluster),
|
||||
// settings = defaultSettings
|
||||
// )
|
||||
|
||||
lazy val fsmSample = Project(
|
||||
id = "akka-sample-fsm",
|
||||
base = file("akka-samples/akka-sample-fsm"),
|
||||
|
|
@ -268,29 +225,6 @@ object AkkaBuild extends Build {
|
|||
settings = defaultSettings
|
||||
)
|
||||
|
||||
// lazy val camelSample = Project(
|
||||
// id = "akka-sample-camel",
|
||||
// base = file("akka-samples/akka-sample-camel"),
|
||||
// dependencies = Seq(actor, camelTyped, testkit % "test"),
|
||||
// settings = defaultSettings ++ Seq(
|
||||
// libraryDependencies ++= Dependencies.sampleCamel
|
||||
// )
|
||||
// )
|
||||
|
||||
// lazy val helloSample = Project(
|
||||
// id = "akka-sample-hello",
|
||||
// base = file("akka-samples/akka-sample-hello"),
|
||||
// dependencies = Seq(kernel),
|
||||
// settings = defaultSettings
|
||||
// )
|
||||
|
||||
// lazy val remoteSample = Project(
|
||||
// id = "akka-sample-remote",
|
||||
// base = file("akka-samples/akka-sample-remote"),
|
||||
// dependencies = Seq(cluster),
|
||||
// settings = defaultSettings
|
||||
// )
|
||||
|
||||
lazy val tutorials = Project(
|
||||
id = "akka-tutorials",
|
||||
base = file("akka-tutorials"),
|
||||
|
|
@ -424,7 +358,7 @@ object Dependencies {
|
|||
val amqp = Seq(rabbit, commonsIo, protobuf)
|
||||
|
||||
val mailboxes = Seq(Test.scalatest, Test.junit)
|
||||
|
||||
|
||||
val fileMailbox = Seq(Test.scalatest, Test.junit)
|
||||
|
||||
val beanstalkMailbox = Seq(beanstalk, Test.junit)
|
||||
|
|
@ -432,13 +366,10 @@ object Dependencies {
|
|||
val redisMailbox = Seq(redis, Test.junit)
|
||||
|
||||
val mongoMailbox = Seq(mongoAsync, twttrUtilCore, Test.junit)
|
||||
|
||||
|
||||
val zookeeperMailbox = Seq(zookeeper, Test.junit)
|
||||
|
||||
// val camel = Seq(camelCore, Test.junit, Test.scalatest, Test.logback)
|
||||
|
||||
val spring = Seq(springBeans, springContext, Test.junit, Test.scalatest)
|
||||
// val spring = Seq(springBeans, springContext, camelSpring, Test.junit, Test.scalatest)
|
||||
|
||||
val kernel = Seq(
|
||||
jettyUtil, jettyXml, jettyServlet, jacksonCore, staxApi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue