#!/bin/bash
#< Advanced JBoss control script
# This script demonstrates several techniques including custom start/stop arguments
# for certain instances, and starting an instance (instance2) in a Solaris project as
# a different user. Also cleans tmp and work directories when server is shutdown. Handles
# an instance (instance2) that doesn't shut down due to buggy code (damn developers ;-))

AWK="/usr/bin/awk"
BASENAME="/usr/bin/basename"
ECHO="/usr/bin/echo"
EGREP="/bin/egrep"
GREP="/bin/grep"
ID="/usr/xpg4/bin/id"
KILL="/bin/kill"
NEWTASK="/usr/bin/newtask"
NOHUP="/usr/bin/nohup"
PS="/usr/ucb/ps"
RM="/usr/bin/rm"
SLEEP="/usr/bin/sleep"
TRUE="/usr/bin/true"
UNAME="/usr/bin/uname"

JBOSS_USER="jboss"
JBOSS2_USER="jboss2"
JBOSS_ROOT="/usr/local/jboss4"
JBOSS_BIN="${JBOSS_ROOT}/bin"
JBOSS_START="run.sh"
JBOSS_STOP="shutdown.sh"
JBOSS_SERVER_ROOT="${JBOSS_ROOT}/server"

THISPROG=$( ${BASENAME} $0 )

ACTION=""
SERVERNAME=""
VERBOSE=0

function print_error {
   ${ECHO} "Error: $@" >&2
}

function print_usage {
   {
      ${ECHO} "Usage: ${THISPROG} [-hv] -s <server_name> -a <start|stop|status>"
      ${ECHO} "     -a Specify action to perform"
      ${ECHO} "        Valid actions:"
      ${ECHO} "           start  - Start this JBoss instance"
      ${ECHO} "           stop   - Stop this JBoss instance"
      ${ECHO} "           status - Check status of this JBoss instance"
      ${ECHO} "     -h Display this usage message"
      ${ECHO} "     -s Specify JBoss server instance"
      ${ECHO} "     -v Verbose mode"
   } >&2
}

function check_os {
   OS=$( ${UNAME} -s )
   case ${OS} in
      "Linux")   : # Linux specific stuff here
                 ;;
      "SunOS")   : # Solaris specific stuff here
                 ;;
      *      )   : # default case stuff here
                 ;;
   esac
}

function check_user {
   CURRENT_USER=$( ${ID} -un )
   if [ "${SERVERNAME}" = "instance2" -a "${CURRENT_USER}" != "${JBOSS2_USER}" ]; then
      print_error "Server ${SERVERNAME} must be started/stopped as ${JBOSS2_USER}" && exit 1
   elif [ "${CURRENT_USER}" != "${JBOSS_USER}" -a "${SERVERNAME}" != "instance2" ]; then
      print_error "This script must be run as user ${JBOSS_USER}" && exit 1
   fi
}

function check_args {
   if [ "${SERVERNAME}" = "" ]; then
      print_error "No server specified" && exit 1
   fi
   if [ "${ACTION}" = "" ]; then
      print_error "No action specified" && exit 1
   fi
   if [ ! -d "${JBOSS_SERVER_ROOT}/${SERVERNAME}" ]; then
      print_error "Server ${SERVERNAME} does not exist" && exit 1
   else
      JBOSS_SERVER="${JBOSS_SERVER_ROOT}/${SERVERNAME}"
      JBOSS_WORK="${JBOSS_SERVER}/work"
      JBOSS_TMP="${JBOSS_SERVER}/tmp"
   fi
   ${ECHO} "${ACTION}" | ${EGREP} "^(start|stop|status)$" >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      print_error "Invalid action specified"
      {
         ${ECHO} "Valid actions:"
         ${ECHO} "   start  - Start this JBoss instance"
         ${ECHO} "   stop   - Stop this JBoss instance"
         ${ECHO} "   status - Check status of this JBoss instance"
      } >&2
      exit 1
   fi
}

function populate_custom_args {
   # populate the CUSTOM_START_ARGS variable for each server you want to start here,
   # otherwise no custom args will be passed
   case ${SERVERNAME} in
      "standalone")  CUSTOM_START_ARGS="-Djboss.bind.address=192.168.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Djava.rmi.server.hostname=somehostname"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Djava.rmi.server.useLocalHostname=false"
		     CUSTOM_STOP_ARGS="--server=jnp://192.168.0.1:1099"
		     ;;
      "instance1")   CUSTOM_START_ARGS="-Djboss.partition.udpGroup=229.0.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Djboss.bind.address=192.168.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Dbind.address=10.0.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -DdefaultDS.username=username -DdefaultDS.password=password"
		     CUSTOM_STOP_ARGS="--server=jnp://somehostname:1199"
                     ;;
      "instance2")   CUSTOM_START_ARGS="-Djboss.partition.udpGroup=229.0.0.2"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Djboss.bind.address=192.168.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Dbind.address=10.0.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -DdefaultDS.username=username -DdefaultDS.password=password"
		     CUSTOM_STOP_ARGS="--server=jnp://somehostname:1299"
                     ;;
      "instance3")   CUSTOM_START_ARGS="-Djboss.partition.udpGroup=229.0.0.3"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Djboss.bind.address=192.168.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Dbind.address=10.0.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -DdefaultDS.username=username -DdefaultDS.password=password"
		     CUSTOM_STOP_ARGS="--server=jnp://somehostname:1399"
                     ;;
      "instance4")   CUSTOM_START_ARGS="-Djboss.partition.udpGroup=229.0.0.4"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Djboss.bind.address=192.168.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -Dbind.address=10.0.0.1"
                     CUSTOM_START_ARGS="${CUSTOM_START_ARGS} -DdefaultDS.username=username -DdefaultDS.password=password"
		     CUSTOM_STOP_ARGS="--server=jnp://somehostname:1499"
                     ;;
   esac
}

function start_server {
   check_server
   if [ "$?" -eq "0" ]; then
      print_error "Server ${SERVERNAME} is already started" && exit 1
   fi
   cd ${JBOSS_BIN}
   (( VERBOSE )) && {
      ${ECHO} "Attempting to start ${SERVERNAME} with the following command:"
      ${ECHO} "${NOHUP} ./${JBOSS_START} -c ${SERVERNAME} ${CUSTOM_START_ARGS} >${SERVERNAME}.out 2>&1 &"
   }
   # added clause to start instance2 in it's project
   if [ "${SERVERNAME}" = "instance2" ]; then
      NOHUP="${NEWTASK} -p ${SERVERNAME} ${NOHUP}"
   fi
   ${NOHUP} ./${JBOSS_START} -c ${SERVERNAME} ${CUSTOM_START_ARGS} >${SERVERNAME}.out 2>&1 &
   ${SLEEP} 5
   server_status
}

function stop_server {
   check_server
   if [ "$?" -eq "1" ]; then
      print_error "Server ${SERVERNAME} is already stopped" && exit 1
   fi
   cd ${JBOSS_BIN}
   (( VERBOSE )) && {
      ${ECHO} "Attempting to stop ${SERVERNAME} with the following command:"
      ${ECHO} "./${JBOSS_STOP} ${CUSTOM_STOP_ARGS} -S"
   }
   ./${JBOSS_STOP} ${CUSTOM_STOP_ARGS} -S
   COUNTER=0
   while [ true ]; do
      ${SLEEP} 5
      (( COUNTER = COUNTER + 1 ))
      check_server
      if [ "$?" -eq "1" ]; then
         ${ECHO} "Server ${SERVERNAME} has been shutdown"
	 cleanup
	 break
      fi
      if [ "${COUNTER}" -eq "5" -a "${SERVERNAME}" = "instance2" ]; then
         # OK - that's long enough for instance2 which likes to misbehave 
         RUNNING_PID=$( ${PS} auwwwx | ${GREP} "^${JBOSS_USER}" | ${GREP} "${SERVERNAME}" | ${GREP} "java" | ${AWK} '{print $2}')
         ${ECHO} "Sending SIGTERM to instance2 [PID: ${RUNNING_PID}]"
         ${KILL} -TERM ${RUNNING_PID}
      elif [ "${COUNTER}" -eq "6" -a "${SERVERNAME}" = "instance2" ]; then
         # OK - that's long enough for instance2 which likes to misbehave 
         RUNNING_PID=$( ${PS} auwwwx | ${GREP} "^${JBOSS_USER}" | ${GREP} "${SERVERNAME}" | ${GREP} "java" | ${AWK} '{print $2}')
         ${ECHO} "Sending SIGKILL to instance2 [PID: ${RUNNING_PID}]"
         ${KILL} -KILL ${RUNNING_PID}
      fi
   done
}

function cleanup {
   (( VERBOSE )) && {
      ${ECHO} "Removing ${JBOSS_WORK}"
   }
   ${RM} -rf ${JBOSS_WORK}
   (( VERBOSE )) && {
      ${ECHO} "Removing ${JBOSS_TMP}"
   }
   ${RM} -rf ${JBOSS_TMP}
}

function server_status {
   check_server 
   if [ "$?" -eq "0" ]; then
      if [ "${ACTION}" = "start" ]; then
         ${ECHO} "Server ${SERVERNAME} has been started"
      else
         ${ECHO} "Server ${SERVERNAME} is started"
      fi
   else
      ${ECHO} "Server ${SERVERNAME} is stopped"
   fi
}

function check_server {
   RUNNING_PROCS=$( ${PS} auwwwx | ${GREP} "^${JBOSS_USER}" | ${GREP} "${SERVERNAME}" | ${GREP} "java" )
   if [ "${RUNNING_PROCS}" = "" ]; then
      return 1
   else
      return 0
   fi
}

#
# main()
#
while getopts ":ha:s:v" OPTION; do
  case ${OPTION} in
     "h")  print_usage && exit 0   ;;
     "a")  ACTION=${OPTARG}        ;;
     "s")  SERVERNAME=${OPTARG}    ;;
     "v")  VERBOSE=1               ;;
     *  )  print_usage && exit 1   ;;
  esac
done

shift $(( ${OPTIND} - 1 ))

if [ "$#" -ne "0" ]; then
   print_usage && exit 1
fi

check_os
check_user
check_args
populate_custom_args

case ${ACTION} in
   "start" )   start_server  ;;
   "stop"  )   stop_server   ;;
   "status")   server_status ;;
esac

exit 0