Added tests for storing, retrieving and removing custom configuration data in cluster storage.

Signed-off-by: Jonas Bonér <jonasremove@jonasboner.com>
This commit is contained in:
Jonas Bonér 2011-06-22 12:03:58 +02:00
parent df8c4dac89
commit 833238cd44
8 changed files with 122 additions and 32 deletions

View file

@ -465,13 +465,22 @@ trait ClusterNode {
*/ */
def send(f: Function1[Any, Any], arg: Any, replicationFactor: Int): List[Future[Any]] def send(f: Function1[Any, Any], arg: Any, replicationFactor: Int): List[Future[Any]]
/**
* Stores a configuration element under a specific key.
* If the key already exists then it will be overwritten.
*/
def setConfigElement(key: String, bytes: Array[Byte]) def setConfigElement(key: String, bytes: Array[Byte])
/** /**
* Returns the config element for the key or NULL if no element exists under the key. * Returns the config element for the key or NULL if no element exists under the key.
* Returns <code>Some(element)</code> if it exists else <code>None</code>
*/ */
def getConfigElement(key: String): Option[Array[Byte]] def getConfigElement(key: String): Option[Array[Byte]]
/**
* Removes configuration element for a specific key.
* Does nothing if the key does not exist.
*/
def removeConfigElement(key: String) def removeConfigElement(key: String)
def getConfigElementKeys: Array[String] def getConfigElementKeys: Array[String]

View file

@ -1143,6 +1143,10 @@ class DefaultClusterNode private[akka] (
// Config // Config
// ======================================= // =======================================
/**
* Stores a configuration element under a specific key.
* If the key already exists then it will be overwritten.
*/
def setConfigElement(key: String, bytes: Array[Byte]) { def setConfigElement(key: String, bytes: Array[Byte]) {
val compressedBytes = if (shouldCompressData) LZF.compress(bytes) else bytes val compressedBytes = if (shouldCompressData) LZF.compress(bytes) else bytes
EventHandler.debug(this, EventHandler.debug(this,
@ -1168,6 +1172,7 @@ class DefaultClusterNode private[akka] (
/** /**
* Returns the config element for the key or NULL if no element exists under the key. * Returns the config element for the key or NULL if no element exists under the key.
* Returns <code>Some(element)</code> if it exists else <code>None</code>
*/ */
def getConfigElement(key: String): Option[Array[Byte]] = try { def getConfigElement(key: String): Option[Array[Byte]] = try {
Some(zkClient.connection.readData(configurationPathFor(key), new Stat, true)) Some(zkClient.connection.readData(configurationPathFor(key), new Stat, true))
@ -1175,6 +1180,10 @@ class DefaultClusterNode private[akka] (
case e: KeeperException.NoNodeException None case e: KeeperException.NoNodeException None
} }
/**
* Removes configuration element for a specific key.
* Does nothing if the key does not exist.
*/
def removeConfigElement(key: String) { def removeConfigElement(key: String) {
ignore[ZkNoNodeException] { ignore[ZkNoNodeException] {
EventHandler.debug(this, EventHandler.debug(this,

View file

@ -305,38 +305,6 @@ class ClusterSpec extends WordSpec with MustMatchers with BeforeAndAfterAll with
node2.stop node2.stop
} }
"be able to set and get config elements" in {
val node1 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "set-get-config-1", port = 9001))
val node2 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "set-get-config-2", port = 9002))
node1.start
node2.start
node1.setConfigElement("key1", "value1".getBytes)
node2.getConfigElement("key1") must be("value1".getBytes)
node2.setConfigElement("key2", "value2".getBytes)
node1.getConfigElement("key2") must be("value2".getBytes)
node1.stop
node2.stop
}
"be able to remove config elements" in {
val node1 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "remove-config-1", port = 9001))
val node2 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "remove-config-2", port = 9002))
node1.start
node2.start
node1.setConfigElement("key1", "value1".getBytes)
node2.getConfigElement("key1") must be("value1".getBytes)
node2.removeConfigElement("key1")
node1.getConfigElement("key1") must be(null)
node1.stop
node2.stop
}
"be able to replicate an actor" in { "be able to replicate an actor" in {
// create actor // create actor
val actorRef = actorOf[MyJavaSerializableActor]("actor-address").start val actorRef = actorOf[MyJavaSerializableActor]("actor-address").start

View file

@ -0,0 +1 @@
akka.event-handler-level = "DEBUG"

View file

@ -0,0 +1 @@
-Dakka.cluster.nodename=node1 -Dakka.cluster.port=9991

View file

@ -0,0 +1 @@
akka.event-handler-level = "DEBUG"

View file

@ -0,0 +1 @@
-Dakka.cluster.nodename=node2 -Dakka.cluster.port=9992

View file

@ -0,0 +1,100 @@
/**
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
*/
package akka.cluster.configuration
import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers
import org.scalatest.BeforeAndAfterAll
import akka.cluster._
import Cluster._
object ConfigurationStorageMultiJvmSpec {
var NrOfNodes = 2
}
class ConfigurationStorageMultiJvmNode1 extends WordSpec with MustMatchers with BeforeAndAfterAll {
import ConfigurationStorageMultiJvmSpec._
"A cluster" must {
"be able to store, read and remove custom configuration data" in {
barrier("start-node-1", NrOfNodes) {
node.start()
}
barrier("start-node-2", NrOfNodes) {
}
barrier("store-config-data-node-1", NrOfNodes) {
node.setConfigElement("key1", "value1".getBytes)
}
barrier("read-config-data-node-2", NrOfNodes) {
}
barrier("remove-config-data-node-2", NrOfNodes) {
}
barrier("try-read-config-data-node-1", NrOfNodes) {
val option = node.getConfigElement("key1")
option.isDefined must be(false)
val elements = node.getConfigElementKeys
elements.size must be(0)
}
node.shutdown()
}
}
override def beforeAll() = {
startLocalCluster()
}
override def afterAll() = {
shutdownLocalCluster()
}
}
class ConfigurationStorageMultiJvmNode2 extends WordSpec with MustMatchers {
import ConfigurationStorageMultiJvmSpec._
"A cluster" must {
"be able to store, read and remove custom configuration data" in {
barrier("start-node-1", NrOfNodes) {
}
barrier("start-node-2", NrOfNodes) {
node.start()
}
barrier("store-config-data-node-1", NrOfNodes) {
}
barrier("read-config-data-node-2", NrOfNodes) {
val option = node.getConfigElement("key1")
option.isDefined must be(true)
option.get must be("value1".getBytes)
val elements = node.getConfigElementKeys
elements.size must be(1)
elements.head must be("key1")
}
barrier("remove-config-data-node-2", NrOfNodes) {
node.removeConfigElement("key1")
}
barrier("try-read-config-data-node-1", NrOfNodes) {
}
node.shutdown()
}
}
}