Merge branch 'master' of git@github.com:jboner/akka
This commit is contained in:
commit
21b1eb43fc
21 changed files with 203 additions and 57 deletions
|
|
@ -26,7 +26,7 @@ import org.apache.hadoop.hbase.util.Bytes
|
||||||
private[akka] object HbaseStorageBackend extends MapStorageBackend[Array[Byte], Array[Byte]] with VectorStorageBackend[Array[Byte]] with RefStorageBackend[Array[Byte]] with Logging {
|
private[akka] object HbaseStorageBackend extends MapStorageBackend[Array[Byte], Array[Byte]] with VectorStorageBackend[Array[Byte]] with RefStorageBackend[Array[Byte]] with Logging {
|
||||||
|
|
||||||
val EMPTY_BYTE_ARRAY = new Array[Byte](0)
|
val EMPTY_BYTE_ARRAY = new Array[Byte](0)
|
||||||
val HBASE_ZOOKEEPER_QUORUM = config.getString("akka.storage.hbase.zookeeper.quorum", "localhost")
|
val HBASE_ZOOKEEPER_QUORUM = config.getString("akka.storage.hbase.zookeeper-quorum", "localhost")
|
||||||
val CONFIGURATION = new HBaseConfiguration
|
val CONFIGURATION = new HBaseConfiguration
|
||||||
val REF_TABLE_NAME = "__REF_TABLE"
|
val REF_TABLE_NAME = "__REF_TABLE"
|
||||||
val VECTOR_TABLE_NAME = "__VECTOR_TABLE"
|
val VECTOR_TABLE_NAME = "__VECTOR_TABLE"
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class PersistenceSpec extends Spec with BeforeAndAfterAll with ShouldMatchers {
|
||||||
import org.apache.hadoop.hbase.client.HBaseAdmin
|
import org.apache.hadoop.hbase.client.HBaseAdmin
|
||||||
import org.apache.hadoop.hbase.client.HTable
|
import org.apache.hadoop.hbase.client.HTable
|
||||||
|
|
||||||
val HBASE_ZOOKEEPER_QUORUM = config.getString("akka.storage.hbase.zookeeper.quorum", "0")
|
val HBASE_ZOOKEEPER_QUORUM = config.getString("akka.storage.hbase.zookeeper-quorum", "0")
|
||||||
HBASE_ZOOKEEPER_QUORUM should not equal ("0")
|
HBASE_ZOOKEEPER_QUORUM should not equal ("0")
|
||||||
HBASE_ZOOKEEPER_QUORUM should equal("localhost")
|
HBASE_ZOOKEEPER_QUORUM should equal("localhost")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
<xsd:attribute name="port" type="xsd:integer" use="required">
|
<xsd:attribute name="port" type="xsd:string" use="required">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>
|
||||||
Port of the remote host.
|
Port of the remote host.
|
||||||
|
|
@ -152,10 +152,10 @@
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
<xsd:attribute name="timeout" type="xsd:long" use="required">
|
<xsd:attribute name="timeout" type="xsd:string" use="required">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>
|
||||||
The default timeout for '!!' invocations.
|
The default timeout for '!!' invocations in milliseconds.
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
|
@ -198,10 +198,10 @@
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
<xsd:attribute name="timeout" type="xsd:long">
|
<xsd:attribute name="timeout" type="xsd:string">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>
|
||||||
The default timeout for '!!' invocations.
|
The default timeout for '!!' invocations in milliseconds.
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
|
@ -260,7 +260,7 @@
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
<xsd:attribute name="port" type="xsd:integer" use="required">
|
<xsd:attribute name="port" type="xsd:string" use="required">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>
|
||||||
Port of the remote host.
|
Port of the remote host.
|
||||||
|
|
@ -334,6 +334,14 @@
|
||||||
<xsd:attribute name="ref" type="xsd:string"/>
|
<xsd:attribute name="ref" type="xsd:string"/>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="config-type">
|
||||||
|
<xsd:attribute name="location" type="xsd:string"/>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<!-- akka conf -->
|
||||||
|
<xsd:element name="property-placeholder" type="config-type"/>
|
||||||
|
|
||||||
<!-- TypedActor -->
|
<!-- TypedActor -->
|
||||||
<xsd:element name="typed-actor" type="typed-actor-type"/>
|
<xsd:element name="typed-actor" type="typed-actor-type"/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,3 +70,24 @@ class ActorForBeanDefinitionParser extends AbstractSingleBeanDefinitionParser wi
|
||||||
*/
|
*/
|
||||||
override def getBeanClass(element: Element): Class[_] = classOf[ActorForFactoryBean]
|
override def getBeanClass(element: Element): Class[_] = classOf[ActorForFactoryBean]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for custom namespace configuration.
|
||||||
|
* @author michaelkober
|
||||||
|
*/
|
||||||
|
class ConfigBeanDefinitionParser extends AbstractSingleBeanDefinitionParser with ActorParser {
|
||||||
|
/*
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
|
||||||
|
*/
|
||||||
|
override def doParse(element: Element, parserContext: ParserContext, builder: BeanDefinitionBuilder) {
|
||||||
|
val location = element.getAttribute(LOCATION)
|
||||||
|
builder.addPropertyValue(LOCATION, location)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
|
||||||
|
*/
|
||||||
|
override def getBeanClass(element: Element): Class[_] = classOf[ConfiggyPropertyPlaceholderConfigurer]
|
||||||
|
|
||||||
|
override def shouldGenerateId() = true
|
||||||
|
}
|
||||||
|
|
@ -6,10 +6,8 @@ package se.scalablesolutions.akka.spring
|
||||||
|
|
||||||
import org.springframework.beans.{BeanUtils,BeansException,BeanWrapper,BeanWrapperImpl}
|
import org.springframework.beans.{BeanUtils,BeansException,BeanWrapper,BeanWrapperImpl}
|
||||||
import se.scalablesolutions.akka.remote.{RemoteClient, RemoteServer}
|
import se.scalablesolutions.akka.remote.{RemoteClient, RemoteServer}
|
||||||
//import org.springframework.beans.factory.BeanFactory
|
|
||||||
import org.springframework.beans.factory.config.AbstractFactoryBean
|
import org.springframework.beans.factory.config.AbstractFactoryBean
|
||||||
import org.springframework.context.{ApplicationContext,ApplicationContextAware}
|
import org.springframework.context.{ApplicationContext,ApplicationContextAware}
|
||||||
//import org.springframework.util.ReflectionUtils
|
|
||||||
import org.springframework.util.StringUtils
|
import org.springframework.util.StringUtils
|
||||||
|
|
||||||
import se.scalablesolutions.akka.actor.{ActorRef, AspectInitRegistry, TypedActorConfiguration, TypedActor,Actor}
|
import se.scalablesolutions.akka.actor.{ActorRef, AspectInitRegistry, TypedActorConfiguration, TypedActor,Actor}
|
||||||
|
|
@ -42,10 +40,10 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
|
||||||
@BeanProperty var typed: String = ""
|
@BeanProperty var typed: String = ""
|
||||||
@BeanProperty var interface: String = ""
|
@BeanProperty var interface: String = ""
|
||||||
@BeanProperty var implementation: String = ""
|
@BeanProperty var implementation: String = ""
|
||||||
@BeanProperty var timeout: Long = _
|
@BeanProperty var timeoutStr: String = ""
|
||||||
@BeanProperty var transactional: Boolean = false
|
@BeanProperty var transactional: Boolean = false
|
||||||
@BeanProperty var host: String = ""
|
@BeanProperty var host: String = ""
|
||||||
@BeanProperty var port: Int = _
|
@BeanProperty var port: String = ""
|
||||||
@BeanProperty var serverManaged: Boolean = false
|
@BeanProperty var serverManaged: Boolean = false
|
||||||
@BeanProperty var serviceName: String = ""
|
@BeanProperty var serviceName: String = ""
|
||||||
@BeanProperty var lifecycle: String = ""
|
@BeanProperty var lifecycle: String = ""
|
||||||
|
|
@ -54,6 +52,20 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
|
||||||
@BeanProperty var property: PropertyEntries = _
|
@BeanProperty var property: PropertyEntries = _
|
||||||
@BeanProperty var applicationContext: ApplicationContext = _
|
@BeanProperty var applicationContext: ApplicationContext = _
|
||||||
|
|
||||||
|
lazy val timeout = parseTimeout
|
||||||
|
|
||||||
|
private def parseTimeout() : Long = {
|
||||||
|
var result = -1L
|
||||||
|
try {
|
||||||
|
result = if (!timeoutStr.isEmpty) timeoutStr.toLong else -1L
|
||||||
|
} catch {
|
||||||
|
case nfe: NumberFormatException =>
|
||||||
|
log.error(nfe, "could not parse timeout %s", timeoutStr)
|
||||||
|
throw nfe
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
// Holds info about if deps have been set or not. Depends on
|
// Holds info about if deps have been set or not. Depends on
|
||||||
// if interface is specified or not. We must set deps on
|
// if interface is specified or not. We must set deps on
|
||||||
// target instance if interface is specified
|
// target instance if interface is specified
|
||||||
|
|
@ -95,7 +107,7 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
|
||||||
|
|
||||||
val typedActor: AnyRef = TypedActor.newInstance(interface.toClass, implementation.toClass, createConfig)
|
val typedActor: AnyRef = TypedActor.newInstance(interface.toClass, implementation.toClass, createConfig)
|
||||||
if (isRemote && serverManaged) {
|
if (isRemote && serverManaged) {
|
||||||
val server = RemoteServer.getOrCreateServer(new InetSocketAddress(host, port))
|
val server = RemoteServer.getOrCreateServer(new InetSocketAddress(host, port.toInt))
|
||||||
if (serviceName.isEmpty) {
|
if (serviceName.isEmpty) {
|
||||||
server.registerTypedActor(interface, typedActor)
|
server.registerTypedActor(interface, typedActor)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -120,14 +132,14 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
|
||||||
}
|
}
|
||||||
if (isRemote) {
|
if (isRemote) {
|
||||||
if (serverManaged) {
|
if (serverManaged) {
|
||||||
val server = RemoteServer.getOrCreateServer(new InetSocketAddress(host, port))
|
val server = RemoteServer.getOrCreateServer(new InetSocketAddress(host, port.toInt))
|
||||||
if (serviceName.isEmpty) {
|
if (serviceName.isEmpty) {
|
||||||
server.register(actorRef)
|
server.register(actorRef)
|
||||||
} else {
|
} else {
|
||||||
server.register(serviceName, actorRef)
|
server.register(serviceName, actorRef)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
actorRef.makeRemote(host, port)
|
actorRef.makeRemote(host, port.toInt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasDispatcher) {
|
if (hasDispatcher) {
|
||||||
|
|
@ -176,7 +188,7 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
|
||||||
private[akka] def createConfig: TypedActorConfiguration = {
|
private[akka] def createConfig: TypedActorConfiguration = {
|
||||||
val config = new TypedActorConfiguration().timeout(Duration(timeout, "millis"))
|
val config = new TypedActorConfiguration().timeout(Duration(timeout, "millis"))
|
||||||
if (transactional) config.makeTransactionRequired
|
if (transactional) config.makeTransactionRequired
|
||||||
if (isRemote && !serverManaged) config.makeRemote(host, port)
|
if (isRemote && !serverManaged) config.makeRemote(host, port.toInt)
|
||||||
if (hasDispatcher) {
|
if (hasDispatcher) {
|
||||||
if (dispatcher.dispatcherType != THREAD_BASED) {
|
if (dispatcher.dispatcherType != THREAD_BASED) {
|
||||||
config.dispatcher(dispatcherInstance())
|
config.dispatcher(dispatcherInstance())
|
||||||
|
|
@ -220,9 +232,8 @@ class ActorForFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with
|
||||||
|
|
||||||
@BeanProperty var interface: String = ""
|
@BeanProperty var interface: String = ""
|
||||||
@BeanProperty var host: String = ""
|
@BeanProperty var host: String = ""
|
||||||
@BeanProperty var port: Int = _
|
@BeanProperty var port: String = ""
|
||||||
@BeanProperty var serviceName: String = ""
|
@BeanProperty var serviceName: String = ""
|
||||||
//@BeanProperty var scope: String = VAL_SCOPE_SINGLETON
|
|
||||||
@BeanProperty var applicationContext: ApplicationContext = _
|
@BeanProperty var applicationContext: ApplicationContext = _
|
||||||
|
|
||||||
override def isSingleton = false
|
override def isSingleton = false
|
||||||
|
|
@ -237,9 +248,9 @@ class ActorForFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with
|
||||||
*/
|
*/
|
||||||
def createInstance: AnyRef = {
|
def createInstance: AnyRef = {
|
||||||
if (interface.isEmpty) {
|
if (interface.isEmpty) {
|
||||||
RemoteClient.actorFor(serviceName, host, port)
|
RemoteClient.actorFor(serviceName, host, port.toInt)
|
||||||
} else {
|
} else {
|
||||||
RemoteClient.typedActorFor(interface.toClass, serviceName, host, port)
|
RemoteClient.typedActorFor(interface.toClass, serviceName, host, port.toInt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ import org.w3c.dom.Element
|
||||||
import scala.collection.JavaConversions._
|
import scala.collection.JavaConversions._
|
||||||
import se.scalablesolutions.akka.util.Logging
|
import se.scalablesolutions.akka.util.Logging
|
||||||
|
|
||||||
import se.scalablesolutions.akka.actor.IllegalActorStateException
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser trait for custom namespace configuration for typed-actor.
|
* Parser trait for custom namespace configuration for typed-actor.
|
||||||
* @author michaelkober
|
* @author michaelkober
|
||||||
|
|
@ -32,7 +30,7 @@ trait ActorParser extends BeanParser with DispatcherParser {
|
||||||
|
|
||||||
if (remoteElement != null) {
|
if (remoteElement != null) {
|
||||||
objectProperties.host = mandatory(remoteElement, HOST)
|
objectProperties.host = mandatory(remoteElement, HOST)
|
||||||
objectProperties.port = mandatory(remoteElement, PORT).toInt
|
objectProperties.port = mandatory(remoteElement, PORT)
|
||||||
objectProperties.serverManaged = (remoteElement.getAttribute(MANAGED_BY) != null) && (remoteElement.getAttribute(MANAGED_BY).equals(SERVER_MANAGED))
|
objectProperties.serverManaged = (remoteElement.getAttribute(MANAGED_BY) != null) && (remoteElement.getAttribute(MANAGED_BY).equals(SERVER_MANAGED))
|
||||||
val serviceName = remoteElement.getAttribute(SERVICE_NAME)
|
val serviceName = remoteElement.getAttribute(SERVICE_NAME)
|
||||||
if ((serviceName != null) && (!serviceName.isEmpty)) {
|
if ((serviceName != null) && (!serviceName.isEmpty)) {
|
||||||
|
|
@ -54,15 +52,7 @@ trait ActorParser extends BeanParser with DispatcherParser {
|
||||||
objectProperties.propertyEntries.add(entry)
|
objectProperties.propertyEntries.add(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
objectProperties.timeoutStr = element.getAttribute(TIMEOUT)
|
||||||
val timeout = element.getAttribute(TIMEOUT)
|
|
||||||
objectProperties.timeout = if ((timeout != null) && (!timeout.isEmpty)) timeout.toLong else -1L
|
|
||||||
} catch {
|
|
||||||
case nfe: NumberFormatException =>
|
|
||||||
log.error(nfe, "could not parse timeout %s", element.getAttribute(TIMEOUT))
|
|
||||||
throw nfe
|
|
||||||
}
|
|
||||||
|
|
||||||
objectProperties.target = mandatory(element, IMPLEMENTATION)
|
objectProperties.target = mandatory(element, IMPLEMENTATION)
|
||||||
objectProperties.transactional = if (element.getAttribute(TRANSACTIONAL).isEmpty) false else element.getAttribute(TRANSACTIONAL).toBoolean
|
objectProperties.transactional = if (element.getAttribute(TRANSACTIONAL).isEmpty) false else element.getAttribute(TRANSACTIONAL).toBoolean
|
||||||
|
|
||||||
|
|
@ -97,7 +87,7 @@ trait ActorForParser extends BeanParser {
|
||||||
val objectProperties = new ActorForProperties()
|
val objectProperties = new ActorForProperties()
|
||||||
|
|
||||||
objectProperties.host = mandatory(element, HOST)
|
objectProperties.host = mandatory(element, HOST)
|
||||||
objectProperties.port = mandatory(element, PORT).toInt
|
objectProperties.port = mandatory(element, PORT)
|
||||||
objectProperties.serviceName = mandatory(element, SERVICE_NAME)
|
objectProperties.serviceName = mandatory(element, SERVICE_NAME)
|
||||||
if (element.hasAttribute(INTERFACE)) {
|
if (element.hasAttribute(INTERFACE)) {
|
||||||
objectProperties.interface = element.getAttribute(INTERFACE)
|
objectProperties.interface = element.getAttribute(INTERFACE)
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ import AkkaSpringConfigurationTags._
|
||||||
class ActorProperties {
|
class ActorProperties {
|
||||||
var typed: String = ""
|
var typed: String = ""
|
||||||
var target: String = ""
|
var target: String = ""
|
||||||
var timeout: Long = _
|
var timeoutStr: String = ""
|
||||||
var interface: String = ""
|
var interface: String = ""
|
||||||
var transactional: Boolean = false
|
var transactional: Boolean = false
|
||||||
var host: String = ""
|
var host: String = ""
|
||||||
var port: Int = _
|
var port: String = ""
|
||||||
var serverManaged: Boolean = false
|
var serverManaged: Boolean = false
|
||||||
var serviceName: String = ""
|
var serviceName: String = ""
|
||||||
var lifecycle: String = ""
|
var lifecycle: String = ""
|
||||||
|
|
@ -38,7 +38,7 @@ class ActorProperties {
|
||||||
builder.addPropertyValue(PORT, port)
|
builder.addPropertyValue(PORT, port)
|
||||||
builder.addPropertyValue("serverManaged", serverManaged)
|
builder.addPropertyValue("serverManaged", serverManaged)
|
||||||
builder.addPropertyValue("serviceName", serviceName)
|
builder.addPropertyValue("serviceName", serviceName)
|
||||||
builder.addPropertyValue(TIMEOUT, timeout)
|
builder.addPropertyValue("timeoutStr", timeoutStr)
|
||||||
builder.addPropertyValue(IMPLEMENTATION, target)
|
builder.addPropertyValue(IMPLEMENTATION, target)
|
||||||
builder.addPropertyValue(INTERFACE, interface)
|
builder.addPropertyValue(INTERFACE, interface)
|
||||||
builder.addPropertyValue(TRANSACTIONAL, transactional)
|
builder.addPropertyValue(TRANSACTIONAL, transactional)
|
||||||
|
|
@ -46,7 +46,11 @@ class ActorProperties {
|
||||||
builder.addPropertyValue(SCOPE, scope)
|
builder.addPropertyValue(SCOPE, scope)
|
||||||
builder.addPropertyValue(DISPATCHER_TAG, dispatcher)
|
builder.addPropertyValue(DISPATCHER_TAG, dispatcher)
|
||||||
builder.addPropertyValue(PROPERTYENTRY_TAG,propertyEntries)
|
builder.addPropertyValue(PROPERTYENTRY_TAG,propertyEntries)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def timeout() : Long = {
|
||||||
|
if (!timeoutStr.isEmpty) timeoutStr.toLong else -1L
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +61,7 @@ class ActorProperties {
|
||||||
class ActorForProperties {
|
class ActorForProperties {
|
||||||
var interface: String = ""
|
var interface: String = ""
|
||||||
var host: String = ""
|
var host: String = ""
|
||||||
var port: Int = _
|
var port: String = ""
|
||||||
var serviceName: String = ""
|
var serviceName: String = ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import AkkaSpringConfigurationTags._
|
||||||
*/
|
*/
|
||||||
class AkkaNamespaceHandler extends NamespaceHandlerSupport {
|
class AkkaNamespaceHandler extends NamespaceHandlerSupport {
|
||||||
def init = {
|
def init = {
|
||||||
|
registerBeanDefinitionParser(CONFIG_TAG, new ConfigBeanDefinitionParser());
|
||||||
registerBeanDefinitionParser(TYPED_ACTOR_TAG, new TypedActorBeanDefinitionParser())
|
registerBeanDefinitionParser(TYPED_ACTOR_TAG, new TypedActorBeanDefinitionParser())
|
||||||
registerBeanDefinitionParser(UNTYPED_ACTOR_TAG, new UntypedActorBeanDefinitionParser())
|
registerBeanDefinitionParser(UNTYPED_ACTOR_TAG, new UntypedActorBeanDefinitionParser())
|
||||||
registerBeanDefinitionParser(SUPERVISION_TAG, new SupervisionBeanDefinitionParser())
|
registerBeanDefinitionParser(SUPERVISION_TAG, new SupervisionBeanDefinitionParser())
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ object AkkaSpringConfigurationTags {
|
||||||
// --- TAGS
|
// --- TAGS
|
||||||
//
|
//
|
||||||
// top level tags
|
// top level tags
|
||||||
|
val CONFIG_TAG = "property-placeholder"
|
||||||
val TYPED_ACTOR_TAG = "typed-actor"
|
val TYPED_ACTOR_TAG = "typed-actor"
|
||||||
val UNTYPED_ACTOR_TAG = "untyped-actor"
|
val UNTYPED_ACTOR_TAG = "untyped-actor"
|
||||||
val SUPERVISION_TAG = "supervision"
|
val SUPERVISION_TAG = "supervision"
|
||||||
|
|
@ -73,6 +74,9 @@ object AkkaSpringConfigurationTags {
|
||||||
val REJECTION_POLICY ="rejection-policy"
|
val REJECTION_POLICY ="rejection-policy"
|
||||||
val MAILBOX_CAPACITY ="mailbox-capacity"
|
val MAILBOX_CAPACITY ="mailbox-capacity"
|
||||||
|
|
||||||
|
// config attribute
|
||||||
|
val LOCATION = "location"
|
||||||
|
|
||||||
// --- VALUES
|
// --- VALUES
|
||||||
//
|
//
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2010 Scalable Solutions AB <http://scalablesolutions.se>
|
||||||
|
*/
|
||||||
|
package se.scalablesolutions.akka.spring
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
|
||||||
|
import org.springframework.core.io.Resource
|
||||||
|
import net.lag.configgy.Configgy
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfiggyPropertyPlaceholderConfigurer. Property resource configurer for configgy files.
|
||||||
|
*/
|
||||||
|
class ConfiggyPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the akka properties as local properties, leaves the location empty.
|
||||||
|
* @param configgyResource akka.conf
|
||||||
|
*/
|
||||||
|
override def setLocation(configgyResource: Resource) {
|
||||||
|
if (configgyResource == null) throw new IllegalArgumentException("Property 'config' must be set")
|
||||||
|
val properties = loadAkkaConfig(configgyResource)
|
||||||
|
setProperties(properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the akka.conf and transform to properties.
|
||||||
|
*/
|
||||||
|
private def loadAkkaConfig(configgyResource: Resource) : Properties = {
|
||||||
|
Configgy.configure(configgyResource.getFile.getPath)
|
||||||
|
val config = Configgy.config
|
||||||
|
val properties = new Properties()
|
||||||
|
config.asMap.foreach {case (k, v) => properties.put(k, v); println("(k,v)=" + k + ", " + v)}
|
||||||
|
properties
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -60,7 +60,8 @@ class SupervisionFactoryBean extends AbstractFactoryBean[AnyRef] {
|
||||||
val isRemote = (props.host != null) && (!props.host.isEmpty)
|
val isRemote = (props.host != null) && (!props.host.isEmpty)
|
||||||
val withInterface = (props.interface != null) && (!props.interface.isEmpty)
|
val withInterface = (props.interface != null) && (!props.interface.isEmpty)
|
||||||
if (isRemote) {
|
if (isRemote) {
|
||||||
val remote = new RemoteAddress(props.host, props.port)
|
//val remote = new RemoteAddress(props.host, props.port)
|
||||||
|
val remote = new RemoteAddress(props.host, props.port.toInt)
|
||||||
if (withInterface) {
|
if (withInterface) {
|
||||||
new Component(props.interface.toClass, props.target.toClass, lifeCycle, props.timeout, props.transactional, remote)
|
new Component(props.interface.toClass, props.target.toClass, lifeCycle, props.timeout, props.transactional, remote)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -91,7 +92,7 @@ class SupervisionFactoryBean extends AbstractFactoryBean[AnyRef] {
|
||||||
}
|
}
|
||||||
|
|
||||||
val supervise = if (isRemote) {
|
val supervise = if (isRemote) {
|
||||||
val remote = new SRemoteAddress(props.host, props.port)
|
val remote = new SRemoteAddress(props.host, props.port.toInt)
|
||||||
Supervise(actorRef, lifeCycle.transform, remote)
|
Supervise(actorRef, lifeCycle.transform, remote)
|
||||||
} else {
|
} else {
|
||||||
Supervise(actorRef, lifeCycle.transform)
|
Supervise(actorRef, lifeCycle.transform)
|
||||||
|
|
|
||||||
13
akka-spring/src/test/resources/akka-test.conf
Normal file
13
akka-spring/src/test/resources/akka-test.conf
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
akka {
|
||||||
|
actor {
|
||||||
|
timeout = 2000
|
||||||
|
}
|
||||||
|
remote {
|
||||||
|
server {
|
||||||
|
service = on
|
||||||
|
hostname = "localhost" # The hostname or IP that clients should connect to
|
||||||
|
port = 9995 # The port clients should connect to
|
||||||
|
connection-timeout = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
akka-spring/src/test/resources/property-config.xml
Normal file
22
akka-spring/src/test/resources/property-config.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:akka="http://www.akkasource.org/schema/akka"
|
||||||
|
xmlns:beans="http://www.springframework.org/schema/lang"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||||
|
http://www.akkasource.org/schema/akka
|
||||||
|
http://scalablesolutions.se/akka/akka-1.0-SNAPSHOT.xsd">
|
||||||
|
|
||||||
|
|
||||||
|
<akka:property-placeholder location="akka-test.conf"/>
|
||||||
|
|
||||||
|
<akka:untyped-actor id="actor-1"
|
||||||
|
implementation="se.scalablesolutions.akka.spring.foo.PingActor"
|
||||||
|
timeout="${akka.actor.timeout}">
|
||||||
|
<akka:remote host="${akka.remote.server.hostname}" port="${akka.remote.server.port}"/>
|
||||||
|
</akka:untyped-actor>
|
||||||
|
|
||||||
|
|
||||||
|
</beans>
|
||||||
|
|
@ -25,8 +25,8 @@ class ActorFactoryBeanTest extends Spec with ShouldMatchers with BeforeAndAfterA
|
||||||
it("should have java getters and setters for all properties") {
|
it("should have java getters and setters for all properties") {
|
||||||
bean.setImplementation("java.lang.String")
|
bean.setImplementation("java.lang.String")
|
||||||
assert(bean.getImplementation == "java.lang.String")
|
assert(bean.getImplementation == "java.lang.String")
|
||||||
bean.setTimeout(1000)
|
bean.setTimeoutStr("1000")
|
||||||
assert(bean.getTimeout == 1000)
|
assert(bean.getTimeoutStr === "1000")
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should create a remote typed actor when a host is set") {
|
it("should create a remote typed actor when a host is set") {
|
||||||
|
|
@ -50,7 +50,7 @@ class ActorFactoryBeanTest extends Spec with ShouldMatchers with BeforeAndAfterA
|
||||||
val bean = new ActorFactoryBean()
|
val bean = new ActorFactoryBean()
|
||||||
bean.setInterface("se.scalablesolutions.akka.spring.PojoInf")
|
bean.setInterface("se.scalablesolutions.akka.spring.PojoInf")
|
||||||
bean.setImplementation("se.scalablesolutions.akka.spring.Pojo")
|
bean.setImplementation("se.scalablesolutions.akka.spring.Pojo")
|
||||||
bean.timeout = 1000
|
bean.timeoutStr = "1000"
|
||||||
bean.typed = AkkaSpringConfigurationTags.TYPED_ACTOR_TAG
|
bean.typed = AkkaSpringConfigurationTags.TYPED_ACTOR_TAG
|
||||||
val entries = new PropertyEntries()
|
val entries = new PropertyEntries()
|
||||||
val entry = new PropertyEntry()
|
val entry = new PropertyEntry()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2010 Scalable Solutions AB <http://scalablesolutions.se>
|
||||||
|
*/
|
||||||
|
package se.scalablesolutions.akka.spring
|
||||||
|
|
||||||
|
|
||||||
|
import foo.{IMyPojo, MyPojo, PingActor}
|
||||||
|
import se.scalablesolutions.akka.dispatch._
|
||||||
|
import org.scalatest.FeatureSpec
|
||||||
|
import org.scalatest.matchers.ShouldMatchers
|
||||||
|
import org.scalatest.junit.JUnitRunner
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory
|
||||||
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader
|
||||||
|
import org.springframework.context.ApplicationContext
|
||||||
|
import org.springframework.context.support.ClassPathXmlApplicationContext
|
||||||
|
import org.springframework.core.io.{ClassPathResource, Resource}
|
||||||
|
import java.util.concurrent._
|
||||||
|
import se.scalablesolutions.akka.actor.{UntypedActor, Actor, ActorRef}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for spring configuration of typed actors.
|
||||||
|
* @author michaelkober
|
||||||
|
*/
|
||||||
|
@RunWith(classOf[JUnitRunner])
|
||||||
|
class ConfiggyPropertyPlaceholderConfigurerSpec extends FeatureSpec with ShouldMatchers {
|
||||||
|
val EVENT_DRIVEN_PREFIX = "akka:event-driven:dispatcher:"
|
||||||
|
|
||||||
|
feature("The ConfiggyPropertyPlaceholderConfigurator") {
|
||||||
|
|
||||||
|
scenario("should provide the akkka config for spring") {
|
||||||
|
val context = new ClassPathXmlApplicationContext("/property-config.xml")
|
||||||
|
val actor1 = context.getBean("actor-1").asInstanceOf[ActorRef]
|
||||||
|
assert(actor1.remoteAddress.get.getHostName === "localhost")
|
||||||
|
assert(actor1.remoteAddress.get.getPort === 9995)
|
||||||
|
assert(actor1.timeout === 2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,12 +16,12 @@ private[akka] class Foo
|
||||||
class SupervisionFactoryBeanTest extends Spec with ShouldMatchers {
|
class SupervisionFactoryBeanTest extends Spec with ShouldMatchers {
|
||||||
|
|
||||||
val restartStrategy = new RestartStrategy(new AllForOne(), 3, 1000, Array(classOf[Throwable]))
|
val restartStrategy = new RestartStrategy(new AllForOne(), 3, 1000, Array(classOf[Throwable]))
|
||||||
val typedActors = List(createTypedActorProperties("se.scalablesolutions.akka.spring.Foo", 1000L))
|
val typedActors = List(createTypedActorProperties("se.scalablesolutions.akka.spring.Foo", "1000"))
|
||||||
|
|
||||||
def createTypedActorProperties(target: String, timeout: Long) : ActorProperties = {
|
private def createTypedActorProperties(target: String, timeout: String) : ActorProperties = {
|
||||||
val properties = new ActorProperties()
|
val properties = new ActorProperties()
|
||||||
properties.target = target
|
properties.target = target
|
||||||
properties.timeout = timeout
|
properties.timeoutStr = timeout
|
||||||
properties
|
properties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ class TypedActorBeanDefinitionParserTest extends Spec with ShouldMatchers {
|
||||||
val props = parser.parseActor(dom(xml).getDocumentElement);
|
val props = parser.parseActor(dom(xml).getDocumentElement);
|
||||||
assert(props != null)
|
assert(props != null)
|
||||||
assert(props.host === "com.some.host")
|
assert(props.host === "com.some.host")
|
||||||
assert(props.port === 9999)
|
assert(props.port === "9999")
|
||||||
assert(!props.serverManaged)
|
assert(!props.serverManaged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ class TypedActorBeanDefinitionParserTest extends Spec with ShouldMatchers {
|
||||||
val props = parser.parseActor(dom(xml).getDocumentElement);
|
val props = parser.parseActor(dom(xml).getDocumentElement);
|
||||||
assert(props != null)
|
assert(props != null)
|
||||||
assert(props.host === "com.some.host")
|
assert(props.host === "com.some.host")
|
||||||
assert(props.port === 9999)
|
assert(props.port === "9999")
|
||||||
assert(props.serviceName === "my-service")
|
assert(props.serviceName === "my-service")
|
||||||
assert(props.serverManaged)
|
assert(props.serverManaged)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<aspectwerkz>
|
|
||||||
<system id="akka">
|
|
||||||
<package name="se.scalablesolutions.akka.actor">
|
|
||||||
<aspect class="TypedActorAspect" />
|
|
||||||
<aspect class="ServerManagedTypedActorAspect" />
|
|
||||||
</package>
|
|
||||||
</system>
|
|
||||||
</aspectwerkz>
|
|
||||||
|
|
@ -167,7 +167,7 @@ akka {
|
||||||
}
|
}
|
||||||
|
|
||||||
hbase {
|
hbase {
|
||||||
zookeeper.quorum = "localhost"
|
zookeeper-quorum = "localhost"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue