Cleaned up cluster node admin script and improved functionality in JMX API.

Signed-off-by: Jonas Bonér <jonas@jonasboner.com>
This commit is contained in:
Jonas Bonér 2012-04-16 11:23:03 +02:00
parent ecc949441a
commit a400b90d87
2 changed files with 109 additions and 133 deletions

View file

@ -317,8 +317,8 @@ object Cluster extends ExtensionId[Cluster] with ExtensionIdProvider {
trait ClusterNodeMBean { trait ClusterNodeMBean {
def getMemberStatus: String def getMemberStatus: String
def getClusterStatus: String def getClusterStatus: String
def getLeader: String
def isLeader: Boolean
def isSingleton: Boolean def isSingleton: Boolean
def isConvergence: Boolean def isConvergence: Boolean
def isAvailable: Boolean def isAvailable: Boolean
@ -448,7 +448,7 @@ class Cluster(system: ExtendedActorSystem) extends Extension { clusterNode ⇒
def self: Member = latestGossip.members def self: Member = latestGossip.members
.find(_.address == remoteAddress) .find(_.address == remoteAddress)
.getOrElse(throw new IllegalStateException("Can't find 'this' Member in the cluster membership ring")) .getOrElse(throw new IllegalStateException("Can't find 'this' Member (" + remoteAddress + ") in the cluster membership ring"))
/** /**
* Latest gossip. * Latest gossip.
@ -468,6 +468,11 @@ class Cluster(system: ExtendedActorSystem) extends Extension { clusterNode ⇒
!members.isEmpty && (remoteAddress == members.head.address) !members.isEmpty && (remoteAddress == members.head.address)
} }
/**
* Get the address of the current leader.
*/
def leader: Address = latestGossip.members.head.address
/** /**
* Is this node a singleton cluster? * Is this node a singleton cluster?
*/ */
@ -523,7 +528,7 @@ class Cluster(system: ExtendedActorSystem) extends Extension { clusterNode ⇒
/** /**
* Try to join this cluster node with the node specified by 'address'. * Try to join this cluster node with the node specified by 'address'.
* A 'Join(thisNodeAddress)'' command is sent to the node to join. * A 'Join(thisNodeAddress)' command is sent to the node to join.
*/ */
def join(address: Address) { def join(address: Address) {
val connection = clusterCommandConnectionFor(address) val connection = clusterCommandConnectionFor(address)
@ -1043,19 +1048,19 @@ class Cluster(system: ExtendedActorSystem) extends Extension { clusterNode ⇒
*/ */
private def createMBean() = { private def createMBean() = {
val mbean = new StandardMBean(classOf[ClusterNodeMBean]) with ClusterNodeMBean { val mbean = new StandardMBean(classOf[ClusterNodeMBean]) with ClusterNodeMBean {
def getMemberStatus: String = clusterNode.status.toString
// JMX attributes (bean-style)
def getMemberStatus: String = clusterNode.status.toString
// FIXME clean up: Gossip(overview = GossipOverview(seen = [], unreachable = []), members = [Member(address = akka://system0@localhost:5550, status = Joining)], meta = [], version = VectorClock(Node(df2691d6cc6779dc2555316f557b5fa4) -> 00000136b164746d)) // FIXME clean up: Gossip(overview = GossipOverview(seen = [], unreachable = []), members = [Member(address = akka://system0@localhost:5550, status = Joining)], meta = [], version = VectorClock(Node(df2691d6cc6779dc2555316f557b5fa4) -> 00000136b164746d))
def getClusterStatus: String = clusterNode.latestGossip.toString def getClusterStatus: String = clusterNode.latestGossip.toString
def getLeader: String = clusterNode.leader.toString
def isLeader: Boolean = clusterNode.isLeader
def isSingleton: Boolean = clusterNode.isSingletonCluster def isSingleton: Boolean = clusterNode.isSingletonCluster
def isConvergence: Boolean = clusterNode.convergence.isDefined def isConvergence: Boolean = clusterNode.convergence.isDefined
def isAvailable: Boolean = clusterNode.isAvailable def isAvailable: Boolean = clusterNode.isAvailable
// JMX commands
def ping(): String = clusterNode.ping def ping(): String = clusterNode.ping
// FIXME return error message if failure
def join(address: String) = clusterNode.join(AddressFromURIString(address)) def join(address: String) = clusterNode.join(AddressFromURIString(address))
def leave(address: String) = clusterNode.leave(AddressFromURIString(address)) def leave(address: String) = clusterNode.leave(AddressFromURIString(address))
def down(address: String) = clusterNode.down(AddressFromURIString(address)) def down(address: String) = clusterNode.down(AddressFromURIString(address))

View file

@ -1,205 +1,176 @@
#!/bin/bash #!/bin/bash
# FIXME allow passing in a hostname:port to override default # FIXME support authentication?
# FIXME leader should return the current leader - not boolean
DEFAULT_HOST="localhost:9999" JMX_CLIENT="java -jar $AKKA_HOME/lib/cmdline-jmxclient-0.10.3.jar -"
SCRIPT=`basename $0`
JMX_CLIENT="java -jar $AKKA_HOME/jmx/cmdline-jmxclient-0.10.3.jar - $DEFAULT_HOST akka:type=Cluster"
# Check the first argument for instructions SELF=`basename $0` # script name
case "$1" in HOST=$1 # cluster node:port to talk to through JMX
join)
function checkNodeIsRunning {
REPLY=$($JMX_CLIENT $HOST akka:type=Cluster ping 2>&1 >/dev/null) # redirects STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running on $HOST"
exit 1
fi
}
case "$2" in
ping)
if [ $# -ne 2 ]; then if [ $# -ne 2 ]; then
echo "Usage: $SCRIPT join <node>" echo "Usage: $SELF <node-hostname:jmx-port> ping"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT join=$@
echo "Pinging $HOST"
$JMX_CLIENT $HOST akka:type=Cluster ping
;;
join)
if [ $# -ne 3 ]; then
echo "Usage: $SELF <node-hostname:jmx-port> join <actor-system-url-to-join>"
exit 1
fi
checkNodeIsRunning
shift
ACTOR_SYSTEM_URL=$2
echo "$HOST is JOINING cluster node $ACTOR_SYSTEM_URL"
$JMX_CLIENT $HOST akka:type=Cluster join=$ACTOR_SYSTEM_URL
;; ;;
leave) leave)
if [ $# -ne 1 ]; then if [ $# -ne 3 ]; then
echo "Usage: $SCRIPT leave" echo "Usage: $SELF <node-hostname:jmx-port> leave <actor-system-url-to-join>"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT leave=$@
ACTOR_SYSTEM_URL=$2
echo "Scheduling $ACTOR_SYSTEM_URL to LEAVE cluster"
$JMX_CLIENT $HOST akka:type=Cluster leave=$ACTOR_SYSTEM_URL
;; ;;
remove) remove)
if [ $# -ne 2 ]; then if [ $# -ne 3 ]; then
echo "Usage: $SCRIPT remove <node>" echo "Usage: $SELF <node-hostname:jmx-port> remove <actor-system-url-to-join>"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT remove=$@
ACTOR_SYSTEM_URL=$2
echo "Scheduling $ACTOR_SYSTEM_URL to REMOVE"
$JMX_CLIENT $HOST akka:type=Cluster remove=$ACTOR_SYSTEM_URL
;; ;;
down) down)
if [ $# -ne 2 ]; then if [ $# -ne 3 ]; then
echo "Usage: $SCRIPT down <node>" echo "Usage: $SELF <node-hostname:jmx-port> down <actor-system-url-to-join>"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT down=$@
ACTOR_SYSTEM_URL=$2
echo "Marking $ACTOR_SYSTEM_URL as DOWN"
$JMX_CLIENT $HOST akka:type=Cluster down=$ACTOR_SYSTEM_URL
;; ;;
member-status) member-status)
if [ $# -ne 1 ]; then if [ $# -ne 2 ]; then
echo "Usage: $SCRIPT member-status" echo "Usage: $SELF <node-hostname:jmx-port> member-status"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT MemberStatus
echo "Querying member status for $HOST"
$JMX_CLIENT $HOST akka:type=Cluster MemberStatus
;; ;;
cluster-status) cluster-status)
if [ $# -ne 1 ]; then if [ $# -ne 2 ]; then
echo "Usage: $SCRIPT cluster-status" echo "Usage: $SELF <node-hostname:jmx-port> cluster-status"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT ClusterStatus
;;
ping) echo "Querying cluster status"
if [ $# -ne 1 ]; then $JMX_CLIENT $HOST akka:type=Cluster ClusterStatus
echo "Usage: $SCRIPT ping"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1
fi
shift
$JMX_CLIENT ping
;; ;;
leader) leader)
if [ $# -ne 1 ]; then if [ $# -ne 2 ]; then
echo "Usage: $SCRIPT leader" echo "Usage: $SELF <node-hostname:jmx-port> leader"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT Leader
echo "Checking leader status"
$JMX_CLIENT $HOST akka:type=Cluster Leader
;; ;;
is-singleton) is-singleton)
if [ $# -ne 1 ]; then if [ $# -ne 2 ]; then
echo "Usage: $SCRIPT is-singleton" echo "Usage: $SELF <node-hostname:jmx-port> is-singleton"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT Singleton
echo "Checking for singleton cluster"
$JMX_CLIENT $HOST akka:type=Cluster Singleton
;; ;;
has-convergence) has-convergence)
if [ $# -ne 1 ]; then if [ $# -ne 2 ]; then
echo "Usage: $SCRIPT is-convergence" echo "Usage: $SELF <node-hostname:jmx-port> is-convergence"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT Convergence
echo "Checking for cluster convergence"
$JMX_CLIENT $HOST akka:type=Cluster Convergence
;; ;;
is-available) is-available)
if [ $# -ne 1 ]; then if [ $# -ne 2 ]; then
echo "Usage: $SCRIPT is-available" echo "Usage: $SELF <node-hostname:jmx-port> is-available"
exit 1
fi
# Make sure the local node IS running
REPLY=$($JMX_CLIENT ping 2>&1 >/dev/null) # redirect STDERR to STDOUT before capturing it
if [[ "$REPLY" != *pong* ]]; then
echo "Akka cluster node is not running"
exit 1 exit 1
fi fi
checkNodeIsRunning
shift shift
$JMX_CLIENT Available
echo "Checking if $ACTOR_SYSTEM_URL is AVAILABLE"
$JMX_CLIENT $HOST akka:type=Cluster Available
;; ;;
*) *)
echo "Usage: $SCRIPT { ping | join | leave | remove | down" echo "Usage: $SELF <node-hostname:jmx-port> { ping | join | leave | remove | down"
echo " member-status | cluster-status | leader" echo " member-status | cluster-status | leader"
echo " is-singleton | has-convergence | is-available }" echo " is-singleton | has-convergence | is-available }"
echo "Examples: $SELF localhost:9999 ping"
echo " $SELF localhost:9999 join akka://service0@localhost:5550"
echo " $SELF localhost:9999 cluster-status"
exit 1 exit 1
;; ;;
esac esac