fixed final issues with AW proxy integration and remaining tests
This commit is contained in:
parent
e0591005ed
commit
bbec315eb2
29 changed files with 933 additions and 866 deletions
|
|
@ -56,5 +56,6 @@
|
||||||
<classpathentry kind="lib" path="/Users/jboner/src/scala/akka/lib/commons-collections-3.2.1.jar"/>
|
<classpathentry kind="lib" path="/Users/jboner/src/scala/akka/lib/commons-collections-3.2.1.jar"/>
|
||||||
<classpathentry kind="lib" path="/Users/jboner/src/scala/akka/lib/commons-lang-2.4.jar"/>
|
<classpathentry kind="lib" path="/Users/jboner/src/scala/akka/lib/commons-lang-2.4.jar"/>
|
||||||
<classpathentry kind="lib" path="/Users/jboner/src/scala/akka/lib/high-scale-lib.jar"/>
|
<classpathentry kind="lib" path="/Users/jboner/src/scala/akka/lib/high-scale-lib.jar"/>
|
||||||
|
<classpathentry kind="lib" path="/Users/jboner/src/scala/akka/lib/jersey-client-1.1.0-ea.jar"/>
|
||||||
<classpathentry kind="output" path="target/classes"/>
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
||||||
|
|
@ -24,31 +24,37 @@
|
||||||
<groupId>com.sun.grizzly</groupId>
|
<groupId>com.sun.grizzly</groupId>
|
||||||
<artifactId>grizzly-servlet-webserver</artifactId>
|
<artifactId>grizzly-servlet-webserver</artifactId>
|
||||||
<version>1.9.9</version>
|
<version>1.9.9</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.jersey</groupId>
|
<groupId>com.sun.jersey</groupId>
|
||||||
<artifactId>jersey-server</artifactId>
|
<artifactId>jersey-server</artifactId>
|
||||||
<version>1.0.3</version>
|
<version>1.0.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.jersey</groupId>
|
<groupId>com.sun.jersey</groupId>
|
||||||
<artifactId>jersey-json</artifactId>
|
<artifactId>jersey-json</artifactId>
|
||||||
<version>1.0.3</version>
|
<version>1.0.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.jersey</groupId>
|
<groupId>com.sun.jersey</groupId>
|
||||||
<artifactId>jersey-client</artifactId>
|
<artifactId>jersey-client</artifactId>
|
||||||
<version>1.1.0-ea</version>
|
<version>1.1.0-ea</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.jersey</groupId>
|
<groupId>com.sun.jersey</groupId>
|
||||||
<artifactId>jersey-atom</artifactId>
|
<artifactId>jersey-atom</artifactId>
|
||||||
<version>1.0.3</version>
|
<version>1.0.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.5</version>
|
<version>4.5</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jmock</groupId>
|
<groupId>org.jmock</groupId>
|
||||||
|
|
|
||||||
|
|
@ -32,17 +32,14 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase {
|
||||||
}).configureActiveObjects(
|
}).configureActiveObjects(
|
||||||
new RestartStrategy(new AllForOne(), 3, 5000), new Component[]{
|
new RestartStrategy(new AllForOne(), 3, 5000), new Component[]{
|
||||||
new Component(
|
new Component(
|
||||||
"foo",
|
|
||||||
Foo.class,
|
Foo.class,
|
||||||
FooImpl.class,
|
|
||||||
new LifeCycle(new Permanent(), 1000),
|
new LifeCycle(new Permanent(), 1000),
|
||||||
1000),
|
10000),
|
||||||
new Component(
|
new Component(
|
||||||
"bar",
|
|
||||||
Bar.class,
|
Bar.class,
|
||||||
BarImpl.class,
|
BarImpl.class,
|
||||||
new LifeCycle(new Permanent(), 1000),
|
new LifeCycle(new Permanent(), 1000),
|
||||||
1000)
|
10000)
|
||||||
}).inject().supervise();
|
}).inject().supervise();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +48,7 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase {
|
||||||
messageLog = "";
|
messageLog = "";
|
||||||
Foo foo = conf.getActiveObject(Foo.class);
|
Foo foo = conf.getActiveObject(Foo.class);
|
||||||
Bar bar = conf.getActiveObject(Bar.class);
|
Bar bar = conf.getActiveObject(Bar.class);
|
||||||
assertTrue(foo.getBar().toString().equals(bar.toString()));
|
assertEquals(foo.getBar(), bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGuiceExternalDependencyInjection() {
|
public void testGuiceExternalDependencyInjection() {
|
||||||
|
|
@ -66,7 +63,7 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase {
|
||||||
String str = conf.getActiveObject(String.class);
|
String str = conf.getActiveObject(String.class);
|
||||||
fail("exception should have been thrown");
|
fail("exception should have been thrown");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertEquals("Class string has not been put under supervision (by passing in the config to the supervise() method", e.getMessage());
|
assertEquals("Class [java.lang.String] has not been put under supervision (by passing in the config to the 'configureActiveObjects' and then invoking 'supervise') method", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,57 +110,4 @@ public class ActiveObjectGuiceConfiguratorTest extends TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Foo {
|
|
||||||
public String foo(String msg);
|
|
||||||
@oneway public void bar(String msg);
|
|
||||||
public void longRunning();
|
|
||||||
public void throwsException();
|
|
||||||
public Bar getBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
class FooImpl implements Foo {
|
|
||||||
@Inject private Bar bar;
|
|
||||||
public Bar getBar() {
|
|
||||||
return bar;
|
|
||||||
}
|
|
||||||
public String foo(String msg) {
|
|
||||||
return msg + "return_foo ";
|
|
||||||
}
|
|
||||||
public void bar(String msg) {
|
|
||||||
bar.bar(msg);
|
|
||||||
}
|
|
||||||
public void longRunning() {
|
|
||||||
try {
|
|
||||||
Thread.sleep(10000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void throwsException() {
|
|
||||||
throw new RuntimeException("expected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Bar {
|
|
||||||
@oneway void bar(String msg);
|
|
||||||
Ext getExt();
|
|
||||||
}
|
|
||||||
|
|
||||||
class BarImpl implements Bar {
|
|
||||||
@Inject private Ext ext;
|
|
||||||
public Ext getExt() {
|
|
||||||
return ext;
|
|
||||||
}
|
|
||||||
public void bar(String msg) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Ext {
|
|
||||||
void ext();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExtImpl implements Ext {
|
|
||||||
public void ext() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
import se.scalablesolutions.akka.annotation.oneway;
|
||||||
|
|
||||||
|
public interface Bar {
|
||||||
|
@oneway
|
||||||
|
void bar(String msg);
|
||||||
|
Ext getExt();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
public class BarImpl implements Bar {
|
||||||
|
@Inject
|
||||||
|
private Ext ext;
|
||||||
|
public Ext getExt() {
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
public void bar(String msg) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
public interface Ext {
|
||||||
|
void ext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
public class ExtImpl implements Ext {
|
||||||
|
public void ext() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import se.scalablesolutions.akka.annotation.oneway;
|
||||||
|
|
||||||
|
public class Foo {
|
||||||
|
@Inject
|
||||||
|
private Bar bar;
|
||||||
|
public Bar getBar() {
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
public String foo(String msg) {
|
||||||
|
return msg + "return_foo ";
|
||||||
|
}
|
||||||
|
@oneway
|
||||||
|
public void bar(String msg) {
|
||||||
|
bar.bar(msg);
|
||||||
|
}
|
||||||
|
public void longRunning() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(10000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void throwsException() {
|
||||||
|
throw new RuntimeException("expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package se.scalablesolutions.akka.api;
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
public interface InMemFailer {
|
public class InMemFailer {
|
||||||
public void fail();
|
public void fail() {
|
||||||
|
throw new RuntimeException("expected");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,68 @@
|
||||||
package se.scalablesolutions.akka.api;
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
import se.scalablesolutions.akka.annotation.state;
|
||||||
import se.scalablesolutions.akka.annotation.transactional;
|
import se.scalablesolutions.akka.annotation.transactional;
|
||||||
|
import se.scalablesolutions.akka.kernel.*;
|
||||||
|
|
||||||
public interface InMemStateful {
|
public class InMemStateful {
|
||||||
// transactional
|
@state private TransactionalMap<String, String> mapState = new InMemoryTransactionalMap<String, String>();
|
||||||
@transactional
|
@state private TransactionalVector<String> vectorState = new InMemoryTransactionalVector<String>();
|
||||||
public void success(String key, String msg);
|
@state private TransactionalRef<String> refState = new TransactionalRef<String>();
|
||||||
|
|
||||||
|
public String getMapState(String key) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
@transactional
|
@transactional
|
||||||
public void failure(String key, String msg, InMemFailer failer);
|
public void success(String key, String msg) {
|
||||||
|
mapState.put(key, msg);
|
||||||
|
vectorState.add(msg);
|
||||||
|
refState.swap(msg);
|
||||||
|
}
|
||||||
|
|
||||||
//@transactional
|
@transactional
|
||||||
//public void clashOk(String key, String msg, InMemClasher clasher);
|
public void failure(String key, String msg, InMemFailer failer) {
|
||||||
|
mapState.put(key, msg);
|
||||||
|
vectorState.add(msg);
|
||||||
|
refState.swap(msg);
|
||||||
|
failer.fail();
|
||||||
|
}
|
||||||
|
|
||||||
//@transactional
|
@transactional
|
||||||
//public void clashNotOk(String key, String msg, InMemClasher clasher);
|
public void thisMethodHangs(String key, String msg, InMemFailer failer) {
|
||||||
|
setMapState(key, msg);
|
||||||
|
}
|
||||||
|
|
||||||
// non-transactional
|
/*
|
||||||
public String getState(String key);
|
public void clashOk(String key, String msg, InMemClasher clasher) {
|
||||||
|
mapState.put(key, msg);
|
||||||
|
clasher.clash();
|
||||||
|
}
|
||||||
|
|
||||||
public void setState(String key, String value);
|
public void clashNotOk(String key, String msg, InMemClasher clasher) {
|
||||||
|
mapState.put(key, msg);
|
||||||
|
clasher.clash();
|
||||||
|
this.success("clash", "clash");
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package se.scalablesolutions.akka.api;
|
|
||||||
|
|
||||||
import se.scalablesolutions.akka.annotation.state;
|
|
||||||
import se.scalablesolutions.akka.kernel.TransactionalMap;
|
|
||||||
import se.scalablesolutions.akka.kernel.InMemoryTransactionalMap;
|
|
||||||
|
|
||||||
public class InMemStatefulImpl implements InMemStateful {
|
|
||||||
@state
|
|
||||||
private TransactionalMap<String, String> state = new InMemoryTransactionalMap<String, String>();
|
|
||||||
|
|
||||||
public String getState(String key) {
|
|
||||||
return state.get(key).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(String key, String msg) {
|
|
||||||
state.put(key, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void success(String key, String msg) {
|
|
||||||
state.put(key, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void failure(String key, String msg, InMemFailer failer) {
|
|
||||||
state.put(key, msg);
|
|
||||||
failer.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
public void clashOk(String key, String msg, InMemClasher clasher) {
|
|
||||||
state.put(key, msg);
|
|
||||||
clasher.clash();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clashNotOk(String key, String msg, InMemClasher clasher) {
|
|
||||||
state.put(key, msg);
|
|
||||||
clasher.clash();
|
|
||||||
this.success("clash", "clash");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
@ -4,11 +4,8 @@
|
||||||
|
|
||||||
package se.scalablesolutions.akka.api;
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
import se.scalablesolutions.akka.annotation.*;
|
|
||||||
import se.scalablesolutions.akka.kernel.config.*;
|
|
||||||
import static se.scalablesolutions.akka.kernel.config.JavaConfig.*;
|
import static se.scalablesolutions.akka.kernel.config.JavaConfig.*;
|
||||||
import se.scalablesolutions.akka.kernel.TransactionalMap;
|
import se.scalablesolutions.akka.kernel.config.*;
|
||||||
import se.scalablesolutions.akka.kernel.InMemoryTransactionalMap;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
|
@ -22,8 +19,8 @@ public class InMemoryStateTest extends TestCase {
|
||||||
new RestartStrategy(new AllForOne(), 3, 5000),
|
new RestartStrategy(new AllForOne(), 3, 5000),
|
||||||
new Component[] {
|
new Component[] {
|
||||||
// FIXME: remove string-name, add ctor to only accept target class
|
// FIXME: remove string-name, add ctor to only accept target class
|
||||||
new Component("inmem-stateful", InMemStateful.class, InMemStatefulImpl.class, new LifeCycle(new Permanent(), 1000), 10000000),
|
new Component(InMemStateful.class, new LifeCycle(new Permanent(), 1000), 10000000),
|
||||||
new Component("inmem-failer", InMemFailer.class, InMemFailerImpl.class, new LifeCycle(new Permanent(), 1000), 1000)
|
new Component(InMemFailer.class, new LifeCycle(new Permanent(), 1000), 1000)
|
||||||
//new Component("inmem-clasher", InMemClasher.class, InMemClasherImpl.class, new LifeCycle(new Permanent(), 1000), 100000)
|
//new Component("inmem-clasher", InMemClasher.class, InMemClasherImpl.class, new LifeCycle(new Permanent(), 1000), 100000)
|
||||||
}).inject().supervise();
|
}).inject().supervise();
|
||||||
}
|
}
|
||||||
|
|
@ -32,25 +29,58 @@ public class InMemoryStateTest extends TestCase {
|
||||||
conf.stop();
|
conf.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testShouldNotRollbackStateForStatefulServerInCaseOfSuccess() {
|
public void testMapShouldNotRollbackStateForStatefulServerInCaseOfSuccess() {
|
||||||
InMemStateful stateful = conf.getActiveObject(InMemStateful.class);
|
InMemStateful stateful = conf.getActiveObject(InMemStateful.class);
|
||||||
stateful.setState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init"); // set init state
|
stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init"); // set init state
|
||||||
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactional
|
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactional
|
||||||
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // to trigger commit
|
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // to trigger commit
|
||||||
assertEquals("new state", stateful.getState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess"));
|
assertEquals("new state", stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testShouldRollbackStateForStatefulServerInCaseOfFailure() {
|
public void testMapShouldRollbackStateForStatefulServerInCaseOfFailure() {
|
||||||
|
InMemStateful stateful = conf.getActiveObject(InMemStateful.class);
|
||||||
|
stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init"); // set init state
|
||||||
|
InMemFailer failer = conf.getActiveObject(InMemFailer.class);
|
||||||
|
try {
|
||||||
|
stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method
|
||||||
|
fail("should have thrown an exception");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
} // expected
|
||||||
|
assertEquals("init", stateful.getMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure")); // check that state is == init state
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testVectorShouldNotRollbackStateForStatefulServerInCaseOfSuccess() {
|
||||||
InMemStateful stateful = conf.getActiveObject(InMemStateful.class);
|
InMemStateful stateful = conf.getActiveObject(InMemStateful.class);
|
||||||
stateful.setState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init"); // set init state
|
stateful.setVectorState("init"); // set init state
|
||||||
InMemFailer failer = conf.getActiveObject(InMemFailer.class);
|
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // transactional
|
||||||
try {
|
stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state"); // to trigger commit
|
||||||
stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method
|
assertEquals("new state", stateful.getVectorState());
|
||||||
fail("should have thrown an exception");
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
} // expected
|
|
||||||
assertEquals("init", stateful.getState("testShouldRollbackStateForStatefulServerInCaseOfFailure")); // check that state is == init state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testVectorShouldRollbackStateForStatefulServerInCaseOfFailure() {
|
||||||
|
InMemStateful stateful = conf.getActiveObject(InMemStateful.class);
|
||||||
|
stateful.setVectorState("init"); // set init state
|
||||||
|
InMemFailer failer = conf.getActiveObject(InMemFailer.class);
|
||||||
|
try {
|
||||||
|
stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method
|
||||||
|
fail("should have thrown an exception");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
} // expected
|
||||||
|
assertEquals("init", stateful.getVectorState()); // check that state is == init state
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNestedNonTransactionalMethodHangs() {
|
||||||
|
InMemStateful stateful = conf.getActiveObject(InMemStateful.class);
|
||||||
|
stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init"); // set init state
|
||||||
|
InMemFailer failer = conf.getActiveObject(InMemFailer.class);
|
||||||
|
try {
|
||||||
|
stateful.thisMethodHangs("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer); // call failing transactional method
|
||||||
|
fail("should have thrown an exception");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
} // expected
|
||||||
|
assertEquals("init", stateful.getMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure")); // check that state is == init state
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
// public void testShouldRollbackStateForStatefulServerInCaseOfMessageClash()
|
// public void testShouldRollbackStateForStatefulServerInCaseOfMessageClash()
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@ import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
|
||||||
@Path("/foo")
|
@Path("/foo")
|
||||||
public interface JerseyFoo {
|
public class JerseyFoo {
|
||||||
@GET
|
@GET
|
||||||
@Produces({"application/json"})
|
@Produces({"application/json"})
|
||||||
public String foo();
|
public String foo() {
|
||||||
|
return "hello foo";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
package se.scalablesolutions.akka.api;
|
|
||||||
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
|
|
||||||
//@Path("/foo")
|
|
||||||
public class JerseyFooImpl implements JerseyFoo {
|
|
||||||
//@GET
|
|
||||||
//@Produces({"application/json"})
|
|
||||||
public String foo() {
|
|
||||||
return "hello foo";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
import se.scalablesolutions.akka.kernel.TransactionalMap;
|
||||||
|
import se.scalablesolutions.akka.kernel.CassandraPersistentTransactionalMap;
|
||||||
|
|
||||||
|
public class PersistentClasher {
|
||||||
|
private TransactionalMap state = new CassandraPersistentTransactionalMap(this);
|
||||||
|
|
||||||
|
public String getState(String key) {
|
||||||
|
return (String)state.get(key).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(String key, String msg) {
|
||||||
|
state.put(key, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clash() {
|
||||||
|
state.put("clasher", "was here");
|
||||||
|
// spend some time here
|
||||||
|
|
||||||
|
// FIXME: this statement gives me this error:
|
||||||
|
// se.scalablesolutions.akka.kernel.ActiveObjectException:
|
||||||
|
// Unexpected message [!(scala.actors.Channel@c2b2f6,ErrRef[Right(null)])]
|
||||||
|
// to
|
||||||
|
// [GenericServer[se.scalablesolutions.akka.api.StatefulImpl]] from
|
||||||
|
// [GenericServer[se.scalablesolutions.akka.api.ClasherImpl]]]
|
||||||
|
// try { Thread.sleep(1000); } catch (InterruptedException e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package se.scalablesolutions.akka.api;
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
public class InMemFailerImpl implements InMemFailer {
|
public class PersistentFailer {
|
||||||
public void fail() {
|
public void fail() {
|
||||||
throw new RuntimeException("expected");
|
throw new RuntimeException("expected");
|
||||||
}
|
}
|
||||||
|
|
@ -6,11 +6,6 @@ package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
import se.scalablesolutions.akka.annotation.*;
|
import se.scalablesolutions.akka.annotation.*;
|
||||||
import se.scalablesolutions.akka.kernel.config.*;
|
import se.scalablesolutions.akka.kernel.config.*;
|
||||||
import se.scalablesolutions.akka.kernel.config.JavaConfig.AllForOne;
|
|
||||||
import se.scalablesolutions.akka.kernel.config.JavaConfig.Component;
|
|
||||||
import se.scalablesolutions.akka.kernel.config.JavaConfig.LifeCycle;
|
|
||||||
import se.scalablesolutions.akka.kernel.config.JavaConfig.Permanent;
|
|
||||||
import se.scalablesolutions.akka.kernel.config.JavaConfig.RestartStrategy;
|
|
||||||
import static se.scalablesolutions.akka.kernel.config.JavaConfig.*;
|
import static se.scalablesolutions.akka.kernel.config.JavaConfig.*;
|
||||||
import se.scalablesolutions.akka.kernel.Kernel;
|
import se.scalablesolutions.akka.kernel.Kernel;
|
||||||
import se.scalablesolutions.akka.kernel.TransactionalMap;
|
import se.scalablesolutions.akka.kernel.TransactionalMap;
|
||||||
|
|
@ -29,11 +24,11 @@ public class PersistentStateTest extends TestCase {
|
||||||
|
|
||||||
protected void setUp() {
|
protected void setUp() {
|
||||||
conf.configureActiveObjects(
|
conf.configureActiveObjects(
|
||||||
new JavaConfig.RestartStrategy(new JavaConfig.AllForOne(), 3, 5000),
|
new RestartStrategy(new AllForOne(), 3, 5000),
|
||||||
new Component[] {
|
new Component[] {
|
||||||
new Component("persistent-stateful", PersistentStateful.class, PersistentStatefulImpl.class, new LifeCycle(new Permanent(), 1000), 10000000),
|
new Component(PersistentStateful.class, new LifeCycle(new Permanent(), 1000), 10000000),
|
||||||
new Component("persistent-failer", PersistentFailer.class, PersistentFailerImpl.class, new LifeCycle(new Permanent(), 1000), 1000),
|
new Component(PersistentFailer.class, new LifeCycle(new Permanent(), 1000), 1000),
|
||||||
new Component("persistent-clasher", PersistentClasher.class, PersistentClasherImpl.class, new LifeCycle(new Permanent(), 1000), 100000)
|
new Component(PersistentClasher.class, new LifeCycle(new Permanent(), 1000), 100000)
|
||||||
}).supervise();
|
}).supervise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,96 +56,3 @@ public class PersistentStateTest extends TestCase {
|
||||||
assertEquals("init", stateful.getState("testShouldRollbackStateForStatefulServerInCaseOfFailure")); // check that state is == init state
|
assertEquals("init", stateful.getState("testShouldRollbackStateForStatefulServerInCaseOfFailure")); // check that state is == init state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PersistentStateful {
|
|
||||||
@transactional
|
|
||||||
public void success(String key, String msg);
|
|
||||||
|
|
||||||
@transactional
|
|
||||||
public void failure(String key, String msg, PersistentFailer failer);
|
|
||||||
|
|
||||||
@transactional
|
|
||||||
public void clashOk(String key, String msg, PersistentClasher clasher);
|
|
||||||
|
|
||||||
@transactional
|
|
||||||
public void clashNotOk(String key, String msg, PersistentClasher clasher);
|
|
||||||
|
|
||||||
public String getState(String key);
|
|
||||||
|
|
||||||
public void setState(String key, String value);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PersistentStatefulImpl implements PersistentStateful {
|
|
||||||
private TransactionalMap state = new CassandraPersistentTransactionalMap(this);
|
|
||||||
|
|
||||||
public String getState(String key) {
|
|
||||||
return (String)state.get(key).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(String key, String msg) {
|
|
||||||
state.put(key, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void success(String key, String msg) {
|
|
||||||
state.put(key, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void failure(String key, String msg, PersistentFailer failer) {
|
|
||||||
state.put(key, msg);
|
|
||||||
failer.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clashOk(String key, String msg, PersistentClasher clasher) {
|
|
||||||
state.put(key, msg);
|
|
||||||
clasher.clash();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clashNotOk(String key, String msg, PersistentClasher clasher) {
|
|
||||||
state.put(key, msg);
|
|
||||||
clasher.clash();
|
|
||||||
clasher.clash();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PersistentFailer {
|
|
||||||
public void fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
class PersistentFailerImpl implements PersistentFailer {
|
|
||||||
public void fail() {
|
|
||||||
throw new RuntimeException("expected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PersistentClasher {
|
|
||||||
public void clash();
|
|
||||||
|
|
||||||
public String getState(String key);
|
|
||||||
|
|
||||||
public void setState(String key, String value);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PersistentClasherImpl implements PersistentClasher {
|
|
||||||
private TransactionalMap state = new CassandraPersistentTransactionalMap(this);
|
|
||||||
|
|
||||||
public String getState(String key) {
|
|
||||||
return (String)state.get(key).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(String key, String msg) {
|
|
||||||
state.put(key, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clash() {
|
|
||||||
state.put("clasher", "was here");
|
|
||||||
// spend some time here
|
|
||||||
|
|
||||||
// FIXME: this statement gives me this error:
|
|
||||||
// se.scalablesolutions.akka.kernel.ActiveObjectException:
|
|
||||||
// Unexpected message [!(scala.actors.Channel@c2b2f6,ErrRef[Right(null)])]
|
|
||||||
// to
|
|
||||||
// [GenericServer[se.scalablesolutions.akka.api.StatefulImpl]] from
|
|
||||||
// [GenericServer[se.scalablesolutions.akka.api.ClasherImpl]]]
|
|
||||||
// try { Thread.sleep(1000); } catch (InterruptedException e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
|
import se.scalablesolutions.akka.kernel.TransactionalMap;
|
||||||
|
import se.scalablesolutions.akka.kernel.CassandraPersistentTransactionalMap;
|
||||||
|
import se.scalablesolutions.akka.annotation.transactional;
|
||||||
|
|
||||||
|
public class PersistentStateful {
|
||||||
|
private TransactionalMap state = new CassandraPersistentTransactionalMap(this);
|
||||||
|
|
||||||
|
public String getState(String key) {
|
||||||
|
return (String)state.get(key).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(String key, String msg) {
|
||||||
|
state.put(key, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@transactional
|
||||||
|
public void success(String key, String msg) {
|
||||||
|
state.put(key, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@transactional
|
||||||
|
public void failure(String key, String msg, PersistentFailer failer) {
|
||||||
|
state.put(key, msg);
|
||||||
|
failer.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
@transactional
|
||||||
|
public void clashOk(String key, String msg, PersistentClasher clasher) {
|
||||||
|
state.put(key, msg);
|
||||||
|
clasher.clash();
|
||||||
|
}
|
||||||
|
|
||||||
|
@transactional
|
||||||
|
public void clashNotOk(String key, String msg, PersistentClasher clasher) {
|
||||||
|
state.put(key, msg);
|
||||||
|
clasher.clash();
|
||||||
|
clasher.clash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package se.scalablesolutions.akka.api;
|
package se.scalablesolutions.akka.api;
|
||||||
|
|
||||||
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
|
|
||||||
import com.sun.jersey.api.client.Client;
|
import com.sun.jersey.api.client.Client;
|
||||||
import com.sun.jersey.api.client.WebResource;
|
import com.sun.jersey.api.client.WebResource;
|
||||||
import com.sun.grizzly.http.SelectorThread;
|
import com.sun.grizzly.http.SelectorThread;
|
||||||
|
|
@ -18,7 +17,6 @@ import javax.servlet.Servlet;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
|
@ -39,9 +37,7 @@ public class RestTest extends TestSuite {
|
||||||
new JavaConfig.RestartStrategy(new JavaConfig.AllForOne(), 3, 5000),
|
new JavaConfig.RestartStrategy(new JavaConfig.AllForOne(), 3, 5000),
|
||||||
new JavaConfig.Component[] {
|
new JavaConfig.Component[] {
|
||||||
new JavaConfig.Component(
|
new JavaConfig.Component(
|
||||||
"jersey-foo",
|
|
||||||
JerseyFoo.class,
|
JerseyFoo.class,
|
||||||
JerseyFooImpl.class,
|
|
||||||
new JavaConfig.LifeCycle(new JavaConfig.Permanent(), 1000), 10000000)
|
new JavaConfig.LifeCycle(new JavaConfig.Permanent(), 1000), 10000000)
|
||||||
}).inject().supervise();
|
}).inject().supervise();
|
||||||
selector = startJersey();
|
selector = startJersey();
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,11 @@ import config.ScalaConfig._
|
||||||
|
|
||||||
import java.util.{List => JList, ArrayList}
|
import java.util.{List => JList, ArrayList}
|
||||||
import java.lang.reflect.{Method, Field}
|
import java.lang.reflect.{Method, Field}
|
||||||
|
import java.lang.annotation.Annotation
|
||||||
|
|
||||||
import org.codehaus.aspectwerkz.intercept.{Advisable, AroundAdvice}
|
import org.codehaus.aspectwerkz.intercept.{Advisable, AroundAdvice}
|
||||||
import org.codehaus.aspectwerkz.joinpoint.{MethodRtti, JoinPoint}
|
import org.codehaus.aspectwerkz.joinpoint.{MethodRtti, JoinPoint}
|
||||||
import org.codehaus.aspectwerkz.proxy.Proxy
|
import org.codehaus.aspectwerkz.proxy.Proxy
|
||||||
import java.lang.annotation.Annotation
|
|
||||||
|
|
||||||
import org.apache.camel.{Processor, Exchange}
|
import org.apache.camel.{Processor, Exchange}
|
||||||
|
|
||||||
|
|
@ -42,8 +43,8 @@ class ActiveObjectFactory {
|
||||||
ActiveObject.newInstance(intf, target, server)
|
ActiveObject.newInstance(intf, target, server)
|
||||||
}
|
}
|
||||||
|
|
||||||
def supervise(restartStrategy: RestartStrategy, components: JList[Worker]): Supervisor =
|
def supervise(restartStrategy: RestartStrategy, components: List[Worker]): Supervisor =
|
||||||
ActiveObject.supervise(restartStrategy, components.toArray.toList.asInstanceOf[List[Worker]])
|
ActiveObject.supervise(restartStrategy, components)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -61,13 +62,13 @@ object ActiveObject {
|
||||||
def newInstance[T](target: Class[T], server: GenericServerContainer): T = {
|
def newInstance[T](target: Class[T], server: GenericServerContainer): T = {
|
||||||
val proxy = Proxy.newInstance(target, false, true)
|
val proxy = Proxy.newInstance(target, false, true)
|
||||||
// FIXME switch to weaving in the aspect at compile time
|
// FIXME switch to weaving in the aspect at compile time
|
||||||
proxy.asInstanceOf[Advisable].aw_addAdvice("execution(* *.*(..))", new ActorAroundAdvice(target, proxy, server))
|
proxy.asInstanceOf[Advisable].aw_addAdvice("execution(* *.*(..))", new TransactionalAroundAdvice(target, proxy, server))
|
||||||
proxy.asInstanceOf[T]
|
proxy.asInstanceOf[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
def newInstance[T](intf: Class[T], target: AnyRef, server: GenericServerContainer): T = {
|
def newInstance[T](intf: Class[T], target: AnyRef, server: GenericServerContainer): T = {
|
||||||
val proxy = Proxy.newInstance(Array(intf), Array(target), false, true)
|
val proxy = Proxy.newInstance(Array(intf), Array(target), false, true)
|
||||||
proxy.asInstanceOf[Advisable].aw_addAdvice("execution(* *.*(..))", new ActorAroundAdvice(intf, target, server))
|
proxy.asInstanceOf[Advisable].aw_addAdvice("execution(* *.*(..))", new TransactionalAroundAdvice(intf, target, server))
|
||||||
proxy.asInstanceOf[T]
|
proxy.asInstanceOf[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,16 +80,6 @@ object ActiveObject {
|
||||||
supervisor ! se.scalablesolutions.akka.kernel.Start
|
supervisor ! se.scalablesolutions.akka.kernel.Start
|
||||||
supervisor
|
supervisor
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
private def supervise(proxy: AnyRef): Supervisor =
|
|
||||||
supervise(
|
|
||||||
RestartStrategy(OneForOne, 5, 1000),
|
|
||||||
Worker(
|
|
||||||
proxy.server,
|
|
||||||
LifeCycle(Permanent, 100))
|
|
||||||
:: Nil)
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -96,9 +87,9 @@ object ActiveObject {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// FIXME: STM that allows concurrent updates, detects collision, rolls back and restarts
|
// FIXME: STM that allows concurrent updates, detects collision, rolls back and restarts
|
||||||
sealed class ActorAroundAdvice(target: Class[_],
|
sealed class TransactionalAroundAdvice(target: Class[_],
|
||||||
targetInstance: AnyRef,
|
targetInstance: AnyRef,
|
||||||
val server: GenericServerContainer) extends AroundAdvice {
|
server: GenericServerContainer) extends AroundAdvice {
|
||||||
val (maps, vectors, refs) = getTransactionalItemsFor(targetInstance)
|
val (maps, vectors, refs) = getTransactionalItemsFor(targetInstance)
|
||||||
server.transactionalRefs = refs
|
server.transactionalRefs = refs
|
||||||
server.transactionalMaps = maps
|
server.transactionalMaps = maps
|
||||||
|
|
@ -109,17 +100,14 @@ sealed class ActorAroundAdvice(target: Class[_],
|
||||||
|
|
||||||
def invoke(joinpoint: JoinPoint): AnyRef = {
|
def invoke(joinpoint: JoinPoint): AnyRef = {
|
||||||
// FIXME: switch to using PCD annotation matching, break out into its own aspect + switch to StaticJoinPoint
|
// FIXME: switch to using PCD annotation matching, break out into its own aspect + switch to StaticJoinPoint
|
||||||
val method = joinpoint.getRtti.asInstanceOf[MethodRtti].getMethod
|
val rtti = joinpoint.getRtti.asInstanceOf[MethodRtti]
|
||||||
|
val method = rtti.getMethod
|
||||||
if (method.isAnnotationPresent(Annotations.transactional)) {
|
if (method.isAnnotationPresent(Annotations.transactional)) {
|
||||||
if (activeTx.isDefined) {
|
if (activeTx.isDefined) {
|
||||||
val tx = activeTx.get
|
val tx = activeTx.get
|
||||||
//val cflowTx = threadBoundTx.get
|
|
||||||
// if (cflowTx.isDefined && cflowTx.get != tx) {
|
|
||||||
// new tx in scope; try to commit
|
|
||||||
tx.commit(server)
|
tx.commit(server)
|
||||||
threadBoundTx.set(None)
|
threadBoundTx.set(None)
|
||||||
activeTx = None
|
activeTx = None
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// FIXME: check if we are already in a transaction if so NEST (set parent)
|
// FIXME: check if we are already in a transaction if so NEST (set parent)
|
||||||
val newTx = new Transaction
|
val newTx = new Transaction
|
||||||
|
|
@ -134,37 +122,14 @@ sealed class ActorAroundAdvice(target: Class[_],
|
||||||
activeTx = Some(currentTx)
|
activeTx = Some(currentTx)
|
||||||
}
|
}
|
||||||
activeTx = threadBoundTx.get
|
activeTx = threadBoundTx.get
|
||||||
invoke(joinpoint, activeTx)
|
|
||||||
//invoke(Invocation(method, joinpoint.getRtti.asInstanceOf[MethodRtti].getParameterValues, targetInstance, activeTx))
|
|
||||||
}
|
|
||||||
|
|
||||||
private def invoke(joinpoint: JoinPoint, tx: Option[Transaction]): AnyRef = {
|
// FIXME: switch to using PCD annotation matching, break out into its own aspect + switch to StaticJoinPoint
|
||||||
val result: AnyRef =
|
val result: AnyRef =
|
||||||
/*
|
if (rtti.getMethod.isAnnotationPresent(Annotations.oneway)) {
|
||||||
if (joinpoint.target.isInstanceOf[MessageDriven] &&
|
server ! (activeTx, joinpoint)
|
||||||
joinpoint.method.getName == "onMessage") {
|
|
||||||
val m = joinpoint.method
|
|
||||||
|
|
||||||
val endpointName = m.getDeclaringClass.getName + "." + m.getName
|
|
||||||
val activeObjectName = m.getDeclaringClass.getName
|
|
||||||
val endpoint = conf.getRoutingEndpoint(conf.lookupUriFor(m))
|
|
||||||
val producer = endpoint.createProducer
|
|
||||||
val exchange = endpoint.createExchange
|
|
||||||
exchange.getIn().setBody(joinpoint)
|
|
||||||
producer.process(exchange)
|
|
||||||
val fault = exchange.getException();
|
|
||||||
if (fault != null) throw new InvocationTargetException(fault)
|
|
||||||
|
|
||||||
// FIXME: need some timeout and future here...
|
|
||||||
exchange.getOut.getBody
|
|
||||||
|
|
||||||
} else */
|
|
||||||
// FIXME: switch to using PCD annotation matching, break out into its own aspect + switch to StaticJoinPoint
|
|
||||||
if (joinpoint.getRtti.asInstanceOf[MethodRtti].getMethod.isAnnotationPresent(Annotations.oneway)) {
|
|
||||||
server ! (tx, joinpoint)
|
|
||||||
} else {
|
} else {
|
||||||
val result: ErrRef[AnyRef] =
|
val result: ErrRef[AnyRef] =
|
||||||
server !!! ((tx, joinpoint), {
|
server !!! ((activeTx, joinpoint), {
|
||||||
var ref = ErrRef(activeTx)
|
var ref = ErrRef(activeTx)
|
||||||
ref() = throw new ActiveObjectInvocationTimeoutException("Invocation to active object [" + targetInstance.getClass.getName + "] timed out after " + server.timeout + " milliseconds")
|
ref() = throw new ActiveObjectInvocationTimeoutException("Invocation to active object [" + targetInstance.getClass.getName + "] timed out after " + server.timeout + " milliseconds")
|
||||||
ref
|
ref
|
||||||
|
|
@ -173,7 +138,6 @@ sealed class ActorAroundAdvice(target: Class[_],
|
||||||
result()
|
result()
|
||||||
} catch {
|
} catch {
|
||||||
case e =>
|
case e =>
|
||||||
println("$$$$$$$$$$$$$$ " + joinpoint)
|
|
||||||
rollback(result.tx)
|
rollback(result.tx)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
|
|
@ -190,29 +154,41 @@ sealed class ActorAroundAdvice(target: Class[_],
|
||||||
threadBoundTx.set(Some(tx))
|
threadBoundTx.set(Some(tx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for transactional items for a specific target instance, crawl the class hierarchy recursively up to the top.
|
||||||
|
*/
|
||||||
private def getTransactionalItemsFor(targetInstance: AnyRef):
|
private def getTransactionalItemsFor(targetInstance: AnyRef):
|
||||||
Tuple3[List[TransactionalMap[_, _]], List[TransactionalVector[_]], List[TransactionalRef[_]]] = {
|
Tuple3[List[TransactionalMap[_, _]], List[TransactionalVector[_]], List[TransactionalRef[_]]] = {
|
||||||
require(targetInstance != null)
|
require(targetInstance != null)
|
||||||
var maps: List[TransactionalMap[_, _]] = Nil
|
var maps: List[TransactionalMap[_, _]] = Nil
|
||||||
var vectors: List[TransactionalVector[_]] = Nil
|
|
||||||
var refs: List[TransactionalRef[_]] = Nil
|
var refs: List[TransactionalRef[_]] = Nil
|
||||||
|
var vectors: List[TransactionalVector[_]] = Nil
|
||||||
|
|
||||||
|
def getTransactionalItemsFor(target: Class[_]):
|
||||||
|
Tuple3[List[TransactionalMap[_, _]], List[TransactionalVector[_]], List[TransactionalRef[_]]] = {
|
||||||
for {
|
for {
|
||||||
field <- targetInstance.getClass.getDeclaredFields.toArray.toList.asInstanceOf[List[Field]]
|
field <- target.getDeclaredFields.toArray.toList.asInstanceOf[List[Field]]
|
||||||
fieldType = field.getType
|
fieldType = field.getType
|
||||||
if fieldType == classOf[TransactionalMap[_, _]] ||
|
if fieldType == classOf[TransactionalMap[_, _]] ||
|
||||||
fieldType == classOf[TransactionalVector[_]] ||
|
fieldType == classOf[TransactionalVector[_]] ||
|
||||||
fieldType == classOf[TransactionalRef[_]]
|
fieldType == classOf[TransactionalRef[_]]
|
||||||
txItem = {
|
txItem = {
|
||||||
field.setAccessible(true)
|
field.setAccessible(true)
|
||||||
field.get(targetInstance)
|
field.get(targetInstance)
|
||||||
|
}
|
||||||
|
if txItem != null
|
||||||
|
} {
|
||||||
|
if (txItem.isInstanceOf[TransactionalMap[_, _]]) maps ::= txItem.asInstanceOf[TransactionalMap[_, _]]
|
||||||
|
else if (txItem.isInstanceOf[TransactionalRef[_]]) refs ::= txItem.asInstanceOf[TransactionalRef[_]]
|
||||||
|
else if (txItem.isInstanceOf[TransactionalVector[_]]) vectors ::= txItem.asInstanceOf[TransactionalVector[_]]
|
||||||
}
|
}
|
||||||
if txItem != null
|
val parent = target.getSuperclass
|
||||||
} {
|
if (parent == null) (maps, vectors, refs)
|
||||||
if (txItem.isInstanceOf[TransactionalMap[_, _]]) maps ::= txItem.asInstanceOf[TransactionalMap[_, _]]
|
else getTransactionalItemsFor(parent)
|
||||||
else if (txItem.isInstanceOf[TransactionalRef[_]]) refs ::= txItem.asInstanceOf[TransactionalRef[_]]
|
|
||||||
else if (txItem.isInstanceOf[TransactionalVector[_]]) vectors ::= txItem.asInstanceOf[TransactionalVector[_]]
|
|
||||||
}
|
}
|
||||||
(maps, vectors, refs)
|
|
||||||
|
// start the search for transactional items, crawl the class hierarchy up until we reach 'null'
|
||||||
|
getTransactionalItemsFor(targetInstance.getClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,56 +224,6 @@ private[kernel] class Dispatcher(val targetName: String) extends GenericServer {
|
||||||
override def toString(): String = "GenericServer[" + targetName + "]"
|
override def toString(): String = "GenericServer[" + targetName + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a snapshot of the current invocation.
|
|
||||||
*
|
|
||||||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
|
||||||
*/
|
|
||||||
private[kernel] case class Invocation(val method: Method,
|
|
||||||
val args: Array[AnyRef],
|
|
||||||
val target: AnyRef,
|
|
||||||
val tx: Option[Transaction]) {
|
|
||||||
method.setAccessible(true)
|
|
||||||
|
|
||||||
def invoke: AnyRef = synchronized {
|
|
||||||
println("======== " + this.toString)
|
|
||||||
if (method.getDeclaringClass.isInterface) {
|
|
||||||
target.getClass.getDeclaredMethod(method.getName, method.getParameterTypes).invoke(target, args:_*)
|
|
||||||
} else method.invoke(target, args:_*)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def toString: String = synchronized {
|
|
||||||
"Invocation [method: " + method.getName + ", args: " + argsToString(args) + ", target: " + target + "]"
|
|
||||||
}
|
|
||||||
|
|
||||||
override def hashCode(): Int = synchronized {
|
|
||||||
var result = HashCode.SEED
|
|
||||||
result = HashCode.hash(result, method)
|
|
||||||
result = HashCode.hash(result, args)
|
|
||||||
result = HashCode.hash(result, target)
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
override def equals(that: Any): Boolean = synchronized {
|
|
||||||
that != null &&
|
|
||||||
that.isInstanceOf[Invocation] &&
|
|
||||||
that.asInstanceOf[Invocation].method == method &&
|
|
||||||
that.asInstanceOf[Invocation].target == target &&
|
|
||||||
isEqual(that.asInstanceOf[Invocation].args, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
private[this] def isEqual(a1: Array[Object], a2: Array[Object]): Boolean =
|
|
||||||
(a1 == null && a2 == null) ||
|
|
||||||
(a1 != null &&
|
|
||||||
a2 != null &&
|
|
||||||
a1.size == a2.size &&
|
|
||||||
a1.zip(a2).find(t => t._1 == t._2).isDefined)
|
|
||||||
|
|
||||||
private[this] def argsToString(array: Array[Object]): String =
|
|
||||||
array.foldLeft("(")(_ + " " + _) + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ublic class CamelInvocationHandler implements InvocationHandler {
|
ublic class CamelInvocationHandler implements InvocationHandler {
|
||||||
private final Endpoint endpoint;
|
private final Endpoint endpoint;
|
||||||
|
|
@ -332,4 +258,24 @@ ublic class CamelInvocationHandler implements InvocationHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (joinpoint.target.isInstanceOf[MessageDriven] &&
|
||||||
|
joinpoint.method.getName == "onMessage") {
|
||||||
|
val m = joinpoint.method
|
||||||
|
|
||||||
|
val endpointName = m.getDeclaringClass.getName + "." + m.getName
|
||||||
|
val activeObjectName = m.getDeclaringClass.getName
|
||||||
|
val endpoint = conf.getRoutingEndpoint(conf.lookupUriFor(m))
|
||||||
|
val producer = endpoint.createProducer
|
||||||
|
val exchange = endpoint.createExchange
|
||||||
|
exchange.getIn().setBody(joinpoint)
|
||||||
|
producer.process(exchange)
|
||||||
|
val fault = exchange.getException();
|
||||||
|
if (fault != null) throw new InvocationTargetException(fault)
|
||||||
|
|
||||||
|
// FIXME: need some timeout and future here...
|
||||||
|
exchange.getOut.getBody
|
||||||
|
|
||||||
|
} else
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
@ -23,6 +23,7 @@ case class HotSwap(code: Option[PartialFunction[Any, Unit]]) extends GenericServ
|
||||||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||||
*/
|
*/
|
||||||
trait GenericServer extends Actor {
|
trait GenericServer extends Actor {
|
||||||
|
private val actorScheduler = new ManagedActorScheduler
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template method implementing the server logic.
|
* Template method implementing the server logic.
|
||||||
|
|
@ -62,6 +63,8 @@ trait GenericServer extends Actor {
|
||||||
|
|
||||||
def act = loop { react { genericBase orElse actorBase } }
|
def act = loop { react { genericBase orElse actorBase } }
|
||||||
|
|
||||||
|
//override protected def scheduler = actorScheduler
|
||||||
|
|
||||||
private def actorBase: PartialFunction[Any, Unit] = hotswap getOrElse body
|
private def actorBase: PartialFunction[Any, Unit] = hotswap getOrElse body
|
||||||
|
|
||||||
private var hotswap: Option[PartialFunction[Any, Unit]] = None
|
private var hotswap: Option[PartialFunction[Any, Unit]] = None
|
||||||
|
|
@ -226,6 +229,7 @@ class GenericServerContainer(
|
||||||
*/
|
*/
|
||||||
def !!: T = {
|
def !!: T = {
|
||||||
require(server != null)
|
require(server != null)
|
||||||
|
println("---------- SERVER " + server + " MESSAGE " + message)
|
||||||
val future: FutureWithTimeout[T] = lock.withReadLock { server !!! message }
|
val future: FutureWithTimeout[T] = lock.withReadLock { server !!! message }
|
||||||
future.receiveWithin(time) match {
|
future.receiveWithin(time) match {
|
||||||
case None => errorHandler
|
case None => errorHandler
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2009 Scalable Solutions.
|
* Copyright (C) 2009 Scalable Solutions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.scalablesolutions.akka.kernel
|
package se.scalablesolutions.akka.kernel
|
||||||
|
|
||||||
|
|
@ -12,7 +12,43 @@ import scala.actors.{FJTaskScheduler2, Scheduler, IScheduler, Actor}
|
||||||
|
|
||||||
// FIXME: add managing interface to this class using JMX
|
// FIXME: add managing interface to this class using JMX
|
||||||
// FIXME: configure one instance per GenericServer
|
// FIXME: configure one instance per GenericServer
|
||||||
object ManagedActorScheduler extends Logging {
|
|
||||||
|
class ManagedActorScheduler extends IScheduler with Logging {
|
||||||
|
protected var threadPoolSize = 10
|
||||||
|
protected val threadPool = Executors.newFixedThreadPool(threadPoolSize)
|
||||||
|
|
||||||
|
def execute(fun: => Unit): Unit = threadPool.execute(new Runnable {
|
||||||
|
def run = {
|
||||||
|
try {
|
||||||
|
fun
|
||||||
|
} catch {
|
||||||
|
case e => log.error("Actor scheduler", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def execute(task: Runnable) = threadPool.execute(new Runnable {
|
||||||
|
def run = {
|
||||||
|
try {
|
||||||
|
task.run
|
||||||
|
} catch {
|
||||||
|
case e => log.error("Actor scheduler", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def tick(a: Actor): Unit = {}
|
||||||
|
|
||||||
|
def shutdown: Unit = threadPool.shutdown
|
||||||
|
|
||||||
|
def onLockup(handler: () => Unit): Unit = {}
|
||||||
|
|
||||||
|
def onLockup(millis: Int)(handler: () => Unit): Unit = {}
|
||||||
|
|
||||||
|
def printActorDump: Unit = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
object GlobalManagedActorScheduler extends Logging {
|
||||||
@volatile private var isRegistered = false
|
@volatile private var isRegistered = false
|
||||||
private var threadPoolSize = 10
|
private var threadPoolSize = 10
|
||||||
|
|
||||||
|
|
@ -24,38 +60,8 @@ object ManagedActorScheduler extends Logging {
|
||||||
fj.shutdown
|
fj.shutdown
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
|
Scheduler.impl = new ManagedActorScheduler
|
||||||
Scheduler.impl = {
|
isRegistered = true
|
||||||
val threadPool = Executors.newFixedThreadPool(threadPoolSize)
|
|
||||||
new IScheduler {
|
|
||||||
def execute(fun: => Unit): Unit = threadPool.execute(new Runnable {
|
|
||||||
def run = {
|
|
||||||
try {
|
|
||||||
fun
|
|
||||||
} catch {
|
|
||||||
case e => log.error("Actor scheduler", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
def execute(task: Runnable) = es.execute(new Runnable {
|
|
||||||
def run = {
|
|
||||||
try {
|
|
||||||
task.run
|
|
||||||
} catch {
|
|
||||||
case e => log.error("Actor scheduler", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
def tick(a: Actor): Unit = {}
|
|
||||||
def shutdown: Unit = { threadPool.shutdown }
|
|
||||||
def onLockup(handler: () => Unit): Unit = {}
|
|
||||||
def onLockup(millis: Int)(handler: () => Unit): Unit = {}
|
|
||||||
def printActorDump: Unit = {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
isRegistered = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,9 +29,10 @@ class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurator with CamelC
|
||||||
private var supervisor: Supervisor = _
|
private var supervisor: Supervisor = _
|
||||||
private var restartStrategy: RestartStrategy = _
|
private var restartStrategy: RestartStrategy = _
|
||||||
private var components: List[Component] = _
|
private var components: List[Component] = _
|
||||||
|
private var workers: List[Worker] = Nil
|
||||||
private var bindings: List[DependencyBinding] = Nil
|
private var bindings: List[DependencyBinding] = Nil
|
||||||
private var configRegistry = new HashMap[Class[_], Component] // TODO is configRegistry needed?
|
private var configRegistry = new HashMap[Class[_], Component] // TODO is configRegistry needed?
|
||||||
private var activeObjectRegistry = new HashMap[Class[_], Tuple2[Component, GenericServerContainer]]
|
private var activeObjectRegistry = new HashMap[Class[_], Tuple4[AnyRef, AnyRef, Component, GenericServerContainer]]
|
||||||
private var activeObjectFactory = new ActiveObjectFactory
|
private var activeObjectFactory = new ActiveObjectFactory
|
||||||
private var camelContext = new DefaultCamelContext
|
private var camelContext = new DefaultCamelContext
|
||||||
private var modules = new java.util.ArrayList[Module]
|
private var modules = new java.util.ArrayList[Module]
|
||||||
|
|
@ -44,23 +45,14 @@ class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurator with CamelC
|
||||||
* @return the active object for the class
|
* @return the active object for the class
|
||||||
*/
|
*/
|
||||||
override def getActiveObject[T](clazz: Class[T]): T = synchronized {
|
override def getActiveObject[T](clazz: Class[T]): T = synchronized {
|
||||||
log.debug("Creating new active object [%s]", clazz.getName)
|
log.debug("Retrieving active object [%s]", clazz.getName)
|
||||||
if (injector == null) throw new IllegalStateException("inject() and/or supervise() must be called before invoking getActiveObject(clazz)")
|
if (injector == null) throw new IllegalStateException("inject() and/or supervise() must be called before invoking getActiveObject(clazz)")
|
||||||
val activeObjectOption: Option[Tuple2[Component, GenericServerContainer]] = activeObjectRegistry.get(clazz)
|
val (proxy, targetInstance, component, server) =
|
||||||
if (activeObjectOption.isDefined) {
|
activeObjectRegistry.getOrElse(clazz, throw new IllegalStateException("Class [" + clazz.getName + "] has not been put under supervision (by passing in the config to the 'configureActiveObjects' and then invoking 'supervise') method"))
|
||||||
val (component, server) = activeObjectOption.get
|
injector.injectMembers(targetInstance)
|
||||||
server.setTimeout(component.timeout)
|
proxy.asInstanceOf[T]
|
||||||
val proxy = if (component.intf == null) { // subclassing proxy
|
|
||||||
activeObjectFactory.newInstance(component.target, server).asInstanceOf[T]
|
|
||||||
} else { // delegating proxy
|
|
||||||
component.target.getConstructor(Array[Class[_]]()).setAccessible(true)
|
|
||||||
val targetInstance = component.target.newInstance.asInstanceOf[AnyRef] // TODO: perhaps need to put in registry
|
|
||||||
activeObjectFactory.newInstance(component.intf, targetInstance, server).asInstanceOf[T]
|
|
||||||
}
|
|
||||||
injector.injectMembers(proxy)
|
|
||||||
proxy
|
|
||||||
} else throw new IllegalStateException("Class [" + clazz.getName + "] has not been put under supervision (by passing in the config to the 'supervise') method")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
override def getActiveObjectProxy(clazz: Class[_]): ActiveObjectProxy = synchronized {
|
override def getActiveObjectProxy(clazz: Class[_]): ActiveObjectProxy = synchronized {
|
||||||
log.debug("Looking up active object proxy [%s]", clazz.getName)
|
log.debug("Looking up active object proxy [%s]", clazz.getName)
|
||||||
|
|
@ -74,7 +66,11 @@ class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurator with CamelC
|
||||||
injector.getInstance(clazz).asInstanceOf[T]
|
injector.getInstance(clazz).asInstanceOf[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getComponentInterfaces: List[Class[_]] = components.map(_.intf)
|
override def getComponentInterfaces: List[Class[_]] =
|
||||||
|
for (c <- components) yield {
|
||||||
|
if (c.intf.isDefined) c.intf.get
|
||||||
|
else c.target
|
||||||
|
}
|
||||||
|
|
||||||
override def getRoutingEndpoint(uri: String): Endpoint = synchronized {
|
override def getRoutingEndpoint(uri: String): Endpoint = synchronized {
|
||||||
camelContext.getEndpoint(uri)
|
camelContext.getEndpoint(uri)
|
||||||
|
|
@ -88,17 +84,46 @@ class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurator with CamelC
|
||||||
camelContext.getEndpoints(uri)
|
camelContext.getEndpoints(uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def configureActiveObjects(restartStrategy: RestartStrategy, components: List[Component]): ActiveObjectConfigurator = synchronized {
|
override def configureActiveObjects(
|
||||||
|
restartStrategy: RestartStrategy,
|
||||||
|
components: List[Component]): ActiveObjectConfigurator = synchronized {
|
||||||
this.restartStrategy = restartStrategy
|
this.restartStrategy = restartStrategy
|
||||||
this.components = components.toArray.toList.asInstanceOf[List[Component]]
|
this.components = components.toArray.toList.asInstanceOf[List[Component]]
|
||||||
bindings = for (c <- this.components)
|
bindings = for (component <- this.components) yield {
|
||||||
yield new DependencyBinding(c.intf, c.target) // build up the Guice interface class -> impl class bindings
|
if (component.intf.isDefined) newDelegatingProxy(component)
|
||||||
|
else newSubclassingProxy(component)
|
||||||
|
}
|
||||||
|
//camelContext.getRegistry.asInstanceOf[JndiRegistry].bind(component.name, activeObjectProxy)
|
||||||
|
//for (method <- component.intf.getDeclaredMethods.toList) registerMethodForUri(method, component.name)
|
||||||
|
//log.debug("Registering active object in Camel context under the name [%s]", component.target.getName)
|
||||||
val deps = new java.util.ArrayList[DependencyBinding](bindings.size)
|
val deps = new java.util.ArrayList[DependencyBinding](bindings.size)
|
||||||
for (b <- bindings) deps.add(b)
|
for (b <- bindings) deps.add(b)
|
||||||
modules.add(new ActiveObjectGuiceModule(deps))
|
modules.add(new ActiveObjectGuiceModule(deps))
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def newSubclassingProxy(component: Component): DependencyBinding = {
|
||||||
|
val targetClass = component.target
|
||||||
|
val server = new GenericServerContainer(targetClass.getName, () => new Dispatcher(component.target.getName))
|
||||||
|
server.setTimeout(component.timeout)
|
||||||
|
workers ::= Worker(server, component.lifeCycle)
|
||||||
|
val proxy = activeObjectFactory.newInstance(targetClass, server).asInstanceOf[AnyRef]
|
||||||
|
activeObjectRegistry.put(targetClass, (proxy, proxy, component, server))
|
||||||
|
new DependencyBinding(targetClass, proxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
private def newDelegatingProxy(component: Component): DependencyBinding = {
|
||||||
|
val targetClass = component.intf.get
|
||||||
|
val server = new GenericServerContainer(targetClass.getName, () => new Dispatcher(component.target.getName))
|
||||||
|
server.setTimeout(component.timeout)
|
||||||
|
workers ::= Worker(server, component.lifeCycle)
|
||||||
|
component.target.getConstructor(Array[Class[_]]()).setAccessible(true)
|
||||||
|
val targetInstance = component.target.newInstance.asInstanceOf[AnyRef] // TODO: perhaps need to put in registry
|
||||||
|
val proxy = activeObjectFactory.newInstance(targetClass, targetInstance, server).asInstanceOf[AnyRef]
|
||||||
|
activeObjectRegistry.put(targetClass, (proxy, targetInstance, component, server))
|
||||||
|
new DependencyBinding(targetClass, proxy)
|
||||||
|
}
|
||||||
|
|
||||||
override def inject: ActiveObjectConfigurator = synchronized {
|
override def inject: ActiveObjectConfigurator = synchronized {
|
||||||
if (injector != null) throw new IllegalStateException("inject() has already been called on this configurator")
|
if (injector != null) throw new IllegalStateException("inject() has already been called on this configurator")
|
||||||
injector = Guice.createInjector(modules)
|
injector = Guice.createInjector(modules)
|
||||||
|
|
@ -107,17 +132,6 @@ class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurator with CamelC
|
||||||
|
|
||||||
override def supervise: ActiveObjectConfigurator = synchronized {
|
override def supervise: ActiveObjectConfigurator = synchronized {
|
||||||
if (injector == null) inject
|
if (injector == null) inject
|
||||||
var workers = new java.util.ArrayList[Worker]
|
|
||||||
for (component <- components) {
|
|
||||||
val target = if (component.intf != null) component.intf // TODO: use Option
|
|
||||||
else component.target
|
|
||||||
val server = new GenericServerContainer(target.getName, () => new Dispatcher(component.target.getName))
|
|
||||||
activeObjectRegistry.put(target, (component, server))
|
|
||||||
workers.add(Worker(server, component.lifeCycle))
|
|
||||||
//camelContext.getRegistry.asInstanceOf[JndiRegistry].bind(component.name, activeObjectProxy)
|
|
||||||
for (method <- component.intf.getDeclaredMethods.toList) registerMethodForUri(method, component.name)
|
|
||||||
log.debug("Registering active object in Camel context under the name [%s]", component.target.getName)
|
|
||||||
}
|
|
||||||
supervisor = activeObjectFactory.supervise(restartStrategy, workers)
|
supervisor = activeObjectFactory.supervise(restartStrategy, workers)
|
||||||
//camelContext.addComponent(AKKA_CAMEL_ROUTING_SCHEME, new ActiveObjectComponent(this))
|
//camelContext.addComponent(AKKA_CAMEL_ROUTING_SCHEME, new ActiveObjectComponent(this))
|
||||||
//camelContext.start
|
//camelContext.start
|
||||||
|
|
@ -154,7 +168,7 @@ class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurator with CamelC
|
||||||
def reset = synchronized {
|
def reset = synchronized {
|
||||||
modules = new java.util.ArrayList[Module]
|
modules = new java.util.ArrayList[Module]
|
||||||
configRegistry = new HashMap[Class[_], Component]
|
configRegistry = new HashMap[Class[_], Component]
|
||||||
activeObjectRegistry = new HashMap[Class[_], Tuple2[Component, GenericServerContainer]]
|
activeObjectRegistry = new HashMap[Class[_], Tuple4[AnyRef, AnyRef, Component, GenericServerContainer]]
|
||||||
methodToUriRegistry = new HashMap[Method, String]
|
methodToUriRegistry = new HashMap[Method, String]
|
||||||
injector = null
|
injector = null
|
||||||
restartStrategy = null
|
restartStrategy = null
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ class ActiveObjectGuiceConfiguratorForJava {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getComponentInterfaces: List[Class[_]] = {
|
def getComponentInterfaces: List[Class[_]] = {
|
||||||
val al = new ArrayList[Class[_]]
|
val al = new ArrayList[Class[_]]
|
||||||
for (c <- INSTANCE.getComponentInterfaces) al.add(c)
|
for (c <- INSTANCE.getComponentInterfaces) al.add(c)
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,18 @@ object ScalaConfig {
|
||||||
case object Transient extends Scope
|
case object Transient extends Scope
|
||||||
case object Temporary extends Scope
|
case object Temporary extends Scope
|
||||||
|
|
||||||
case class Component(val name: String,
|
class Component(_intf: Class[_],
|
||||||
val intf: Class[_],
|
|
||||||
val target: Class[_],
|
val target: Class[_],
|
||||||
val lifeCycle: LifeCycle,
|
val lifeCycle: LifeCycle,
|
||||||
val timeout: Int) extends Server
|
val timeout: Int) extends Server {
|
||||||
|
val intf: Option[Class[_]] = if (_intf == null) None else Some(_intf)
|
||||||
|
}
|
||||||
|
object Component {
|
||||||
|
def apply(intf: Class[_], target: Class[_], lifeCycle: LifeCycle, timeout: Int) =
|
||||||
|
new Component(intf, target, lifeCycle, timeout)
|
||||||
|
def apply(target: Class[_], lifeCycle: LifeCycle, timeout: Int) =
|
||||||
|
new Component(null, target, lifeCycle, timeout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -81,13 +88,14 @@ object JavaConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Server extends ConfigElement
|
abstract class Server extends ConfigElement
|
||||||
class Component(@BeanProperty val name: String,
|
class Component(@BeanProperty val intf: Class[_],
|
||||||
@BeanProperty val intf: Class[_],
|
|
||||||
@BeanProperty val target: Class[_],
|
@BeanProperty val target: Class[_],
|
||||||
@BeanProperty val lifeCycle: LifeCycle,
|
@BeanProperty val lifeCycle: LifeCycle,
|
||||||
@BeanProperty val timeout: Int) extends Server {
|
@BeanProperty val timeout: Int) extends Server {
|
||||||
|
def this(target: Class[_], lifeCycle: LifeCycle, timeout: Int) =
|
||||||
|
this(null, target, lifeCycle, timeout)
|
||||||
def transform = se.scalablesolutions.akka.kernel.config.ScalaConfig.Component(
|
def transform = se.scalablesolutions.akka.kernel.config.ScalaConfig.Component(
|
||||||
name, intf, target, lifeCycle.transform, timeout)
|
intf, target, lifeCycle.transform, timeout)
|
||||||
def newWorker(server: GenericServerContainer) =
|
def newWorker(server: GenericServerContainer) =
|
||||||
se.scalablesolutions.akka.kernel.config.ScalaConfig.Worker(server, lifeCycle.transform)
|
se.scalablesolutions.akka.kernel.config.ScalaConfig.Worker(server, lifeCycle.transform)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,30 +32,29 @@ class JerseySpec extends Spec with ShouldMatchers {
|
||||||
|
|
||||||
describe("A Jersey REST service") {
|
describe("A Jersey REST service") {
|
||||||
it("should ...") {
|
it("should ...") {
|
||||||
//val selector = startJersey
|
val selector = startJersey
|
||||||
//oselector.start
|
selector.start
|
||||||
|
/*
|
||||||
val conf = new ActiveObjectGuiceConfigurator
|
val conf = new ActiveObjectGuiceConfigurator
|
||||||
conf.configureActiveObjects(
|
conf.configureActiveObjects(
|
||||||
RestartStrategy(AllForOne, 3, 5000),
|
RestartStrategy(AllForOne, 3, 5000),
|
||||||
Component(
|
Component(
|
||||||
"jerseyfoo",
|
|
||||||
classOf[resource.JerseyFoo],
|
classOf[resource.JerseyFoo],
|
||||||
classOf[resource.JerseyFooImpl],
|
|
||||||
LifeCycle(Permanent, 1000),
|
LifeCycle(Permanent, 1000),
|
||||||
1000) ::
|
1000) ::
|
||||||
Nil).supervise
|
Nil).supervise
|
||||||
|
|
||||||
conf.getActiveObject(classOf[resource.JerseyFoo])
|
conf.getActiveObject(classOf[resource.JerseyFoo])
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
val client = Client.create
|
val client = Client.create
|
||||||
val webResource = client.resource(UriBuilder.fromUri("http://localhost/").port(9998).build)
|
val webResource = client.resource(UriBuilder.fromUri("http://localhost/").port(9998).build)
|
||||||
//val webResource = client.resource("http://localhost:9998/foo")
|
//val webResource = client.resource("http://localhost:9998/foo")
|
||||||
val responseMsg = webResource.get(classOf[String])
|
val responseMsg = webResource.get(classOf[String])
|
||||||
responseMsg should equal ("Hello World")
|
responseMsg should equal ("Hello World")
|
||||||
selector.stopEndpoint
|
selector.stopEndpoint
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,20 +78,14 @@ class JerseySpec extends Spec with ShouldMatchers {
|
||||||
package resource {
|
package resource {
|
||||||
import javax.ws.rs.{Produces, Path, GET}
|
import javax.ws.rs.{Produces, Path, GET}
|
||||||
|
|
||||||
trait JerseyFoo {
|
class JerseyFoo {
|
||||||
def foo: String
|
|
||||||
}
|
|
||||||
trait JerseyBar {
|
|
||||||
def bar(msg: String): String
|
|
||||||
}
|
|
||||||
|
|
||||||
@Path("/foo")
|
|
||||||
class JerseyFooImpl extends JerseyFoo {
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(Array("application/json"))
|
@Produces(Array("application/json"))
|
||||||
def foo: String = { val ret = "JerseyFoo.foo"; println(ret); ret }
|
def foo: String = { val ret = "JerseyFoo.foo"; println(ret); ret }
|
||||||
}
|
}
|
||||||
class JerseyBarImpl extends JerseyBar {
|
@Path("/foo")
|
||||||
|
class JerseyFooSub extends JerseyFoo
|
||||||
|
class JerseyBar {
|
||||||
def bar(msg: String) = msg + "return_bar "
|
def bar(msg: String) = msg + "return_bar "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,9 @@ public class ActiveObjectGuiceModule extends AbstractModule {
|
||||||
bind(ResourceProviderFactory.class);
|
bind(ResourceProviderFactory.class);
|
||||||
for (int i = 0; i < bindings.size(); i++) {
|
for (int i = 0; i < bindings.size(); i++) {
|
||||||
final DependencyBinding db = bindings.get(i);
|
final DependencyBinding db = bindings.get(i);
|
||||||
bind((Class) db.getInterface()).to((Class) db.getTarget()).in(Singleton.class);
|
//if (db.getInterface() != null) bind((Class) db.getInterface()).to((Class) db.getTarget()).in(Singleton.class);
|
||||||
|
//else
|
||||||
|
this.bind(db.getInterface()).toInstance(db.getTarget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,16 @@ package se.scalablesolutions.akka.kernel.config;
|
||||||
*/
|
*/
|
||||||
public class DependencyBinding {
|
public class DependencyBinding {
|
||||||
private final Class intf;
|
private final Class intf;
|
||||||
private final Class target;
|
private final Object target;
|
||||||
|
|
||||||
public DependencyBinding(final Class intf, final Class target) {
|
public DependencyBinding(final Class intf, final Object target) {
|
||||||
this.intf = intf;
|
this.intf = intf;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
public Class getInterface() {
|
public Class getInterface() {
|
||||||
return intf;
|
return intf;
|
||||||
}
|
}
|
||||||
public Class getTarget() {
|
public Object getTarget() {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue