#!/bin/sh
# cms           Start and Stops Watchpoint Content Management System Service
#
# Authors:      Matthew Kruer <matthew.kruer@ericsson.com>
#               Hovey Yu <hovey.yu@ericsson.com>
#
# description:  Ericsson / SA Media Watchpoint CMS Start Up Script
# processname:  org.jboss.Main (java)
# config:       NONE
# pidfile:      /var/run/cms.pid

### BEGIN INIT INFO
# Should-Start: $remote_fs $network
# Required-Start: sshd consul adinameserver
# Provides: cms
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: Content Management System Service
### END INIT INFO

PROGNAME="cms"

# Source function library.
. /etc/rc.d/init.d/functions

# Log output
LOG_FILE="/var/log/messages"

log_output() {
    printf "$1\n"
    #echo "$(date '+%b %d %T') $(hostname -s) $PROGNAME: $1" >> $LOG_FILE
    logger -t $PROGNAME "$1"
}

log_output_verbose () {
    if [[ $VERBOSE_OUT == true ]]; then
        printf "$1"
    fi
    #echo "$(date '+%b %d %T') $(hostname -s) $PROGNAME: $1" >> $LOG_FILE
    logger -t $PROGNAME "$1"
}

PID_FILE="/var/run/$PROGNAME.pid"
LOCK_FILE="/var/lock/subsys/$PROGNAME"

PRODUCT_HOME=/opt/tandbergtv/cms
JAVA_HOME=/usr/java/default/bin
JSTACK_CMD=$JAVA_HOME/jstack

DB_SETTINGS="/opt/db/scripts/install/settings"

if [[ -f $DB_SETTINGS ]]; then
    . "$DB_SETTINGS"
fi

SUDB="${DB_NAME:-ttv}"
SUSER="${DB_USER:-postgres}"
DB_VER="${DB_VERSION:-9.5}"
PSQLHOME="/usr/pgsql-${DB_VER}/bin"
PORT=${DB_PORT:-5432}

# Clear out any existing values just in case
PRE_JAVA_OPTS=""
JAVA_OPTS=""
SERVER_OPTS=""

# Define the user under which jboss will run, or use RUNASIS to run as the current user
JBOSSUS=${JBOSSUS:-"nobody"}

#define where jboss is - this is the directory containing directories log, bin, conf etc
JBOSS_HOME=${JBOSS_HOME:-"/opt/tandbergtv/jboss"}

if [ ! -d "$JBOSS_HOME" ]; then
    log_output "Failed: JBOSS_HOME does not exist as a valid directory : $JBOSS_HOME"
    exit 1
fi

# Setup the java endorsed dirs
JBOSS_ENDORSED_DIRS="$JBOSS_HOME/lib/endorsed"

#define the classpath for the shutdown class
JBOSSCP=${JBOSSCP:-"$JBOSS_HOME/bin/shutdown.jar"}

# Setup the classpath
JBOSS_BOOT_CLASSPATH="$JBOSS_HOME/bin/run.jar"
JBOSS_CLASSPATH="$JBOSS_BOOT_CLASSPATH:$PRODUCT_HOME/workflow/lib:/usr/local/platform/lib/SignatureVerifier.jar"

# Customer Properties are now set via the /opt/tandbergtv/cms/conf/cms/setenv.sh file.
CONF_FILE="/opt/tandbergtv/cms/conf/cms/setenv.sh"
if [[ -f $CONF_FILE ]]; then
    . "$CONF_FILE"
else
    log_output "Failed: Unable to locate $CONF_FILE"
    exit 1
fi

# Additional Java Properties
PRE_JAVA_OPTS="$PRE_JAVA_OPTS -Dprogram.name=$PROGNAME"
PRE_JAVA_OPTS="$PRE_JAVA_OPTS -Djacorb.home=$PRODUCT_HOME/conf/adiserver"
PRE_JAVA_OPTS="$PRE_JAVA_OPTS -Dcom.tandbergtv.cms.product.dir=$PRODUCT_HOME"
PRE_JAVA_OPTS="$PRE_JAVA_OPTS -Dcom.tandbergtv.workflow.message.origin=true"
SERVER_OPTS="$SERVER_OPTS -Dnetworkaddress.cache.ttl=0"
SERVER_OPTS="$SERVER_OPTS -Dnetworkaddress.cache.negative.ttl=0"
SERVER_OPTS="$SERVER_OPTS -Djava.net.preferIPv4Stack=true"
SERVER_OPTS="$SERVER_OPTS -Djboss.modules.system.pkgs=org.jboss.byteman -jar $JBOSS_HOME/jboss-modules.jar"
SERVER_OPTS="$SERVER_OPTS -mp $JBOSS_HOME/modules -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone"
SERVER_OPTS="$SERVER_OPTS -Djboss.home.dir=$JBOSS_HOME"
SERVER_OPTS="$SERVER_OPTS -Djboss.server.base.dir=$JBOSS_HOME/standalone"
SERVER_OPTS="$SERVER_OPTS -Dorg.apache.coyote.http11.Http11Protocol.SERVER=Ericsson-CMS"
SERVER_OPTS="$SERVER_OPTS -b 0.0.0.0 --server-config=standalone.xml"

CMD_START="env LANG=en_US.UTF-8 $JAVA_HOME/java -server $PRE_JAVA_OPTS $JAVA_OPTS $SERVER_OPTS"


# Checks to see if the license key is installed
licensekey_check() {
    if [[ -f "/opt/tandbergtv/cms/conf/neptune/license.xml" ]]; then
        true
    else
        log_output "Failed: CMS license.xml not found; Aborting start up of CMS"
        exit 1
    fi
}

DB_TYPE="${DB_TYPE:-postgres}"
AZURE_DB="${AZURE_DB:-edb1}"

if [ "X${DB_TYPE}" = "Xazure" ]; then
     SUSER="${SUSER}@${AZURE_DB}"
fi

dbserver_check() {
    if [[ -f "${PSQLHOME}/psql" ]] ; then
        count=0
        delay=1
        timeout=30
        dbstate=1
        printf "  Checking Database..."
        while [[ $count -le $timeout && $dbstate > 0 ]] ; do
            sleep $delay
            `PGPASSWORD=${DB_ADMIN_PW:-'n2bbsys'} ${PSQLHOME}/psql -d ${SUDB} -U ${SUSER} -h dbserver -p ${PORT} -c "select now()" >  /dev/null 2>&1`
            dbstate=`echo $?`
            if [[ $count -ge $timeout && $dbstate > 0 ]]; then
                log_output "Failed: Unable to connect to the Database after $timeout Seconds"
                exit 1
            elif [[ $? > 0 ]]  ; then
                printf "."
                count=$(( $count + $delay ))
            else
                count=$(( $count + $timeout ))
            fi
        done
        printf "\n"
    else
        log_output "Warning: psql missing from appliance, continuing to start cms"
    fi
}

es_check() {
    printf "  Checking Elasticsearch..."
    TIME=0
    while [ "$(curl -s -o /dev/null -w '%{http_code}' http://es-nodes.service.consul:9200/)" != "200" ]; do
        if [ $TIME -gt 30 ] ; then
            log_output "Failed: Could not connect to Elasticsearch after 30 seconds. Aborting"
            exit 1
        fi
        sleep 10
        TIME=$((TIME + 10))
        printf "."
    done
    printf "\n"
}

rabbitmq_check() {
    timeoutDuration=30
    delay=10
    timeoutCounter=30
    printf "  Checking RabbitMQ... "
    while true; do
        rabbitmq_count=$(curl -m 10 -s http://app:8501/v1/health/service/rabbitmq-server?passing | jq -r '. | length')
        if [ ! -z "$rabbitmq_count" ] && [ "$rabbitmq_count" -gt 0 ] ; then
            break
        fi
        if [[ $timeoutCounter -le 0 ]]; then
            log_output "Warning: The required RabbitMQ service has not started after waiting for $timeoutDuration seconds; Continue to start workflow. \n"
            break
        fi
        sleep $delay
        timeoutCounter=$(( $timeoutCounter - $delay ))
    done
    printf "\n"
}


cms_shutdown_cleanup() {
    #printf "  Purging temporary jboss files... This may take a while\n"
    if [[ "$(ls -A $JBOSS_HOME/standalone/tmp)" ]] ; then
        `rm -rf $JBOSS_HOME/standalone/tmp/* >/dev/null 2>&1 &`
    fi
}

checkJava() {
    if [ -x "$JAVA_HOME/bin/java" ]; then
        JAVA="$JAVA_HOME/bin/java"
    else
        JAVA=`which java`
    fi

    if [ ! -x "$JAVA" ]; then
        echo "Could not find any executable java binary. Please install java in your PATH or set JAVA_HOME"
        exit 1
    fi
}

start() {
    if [ -n "$PID_FILE" ] && [ ! -e "$PID_FILE" ]; then
        touch "$PID_FILE"
    fi
    checkJava
    licensekey_check
    dbserver_check
    es_check
    rabbitmq_check
    /bin/rm -f /opt/tandbergtv/jboss/standalone/deployments/*.{dodeploy,isdeploying,deployed,failed,isundeploying,undeployed,pending}

    echo -n $"Starting $PROGNAME: "
    # if not running, start it up here, usually something like "daemon $exec"
    runuser $JBOSSUS -c "$CMD_START >/dev/null 2>&1 &"
    count=0
    delay=1
    timeout=3
    while :; do
        #pid=$(pgrep -P $!)
        pid=$(ps axw | grep "[D]program.name=$PROGNAME" | sed -e 's/^\s*//' | cut -d' ' -f1)
        if [[ -n "$pid" ]]; then
            echo_success
            retval=0
            logger -t $PROGNAME "Starting $PROGNAME: [OK]"
            echo
            echo $pid > $PID_FILE
            touch $LOCK_FILE
            break
        elif [[ $count -ge $timeout ]]; then
            echo_failure
            retval=1
            logger -t $PROGNAME "Starting $PROGNAME: [FAILED]"
            echo
            break
        else
            sleep $delay
            count=$(( $count + $delay ))
        fi
    done
    return $retval
}

stop() {
    su $JBOSSUS -c "$JSTACK_CMD -l $(<$PID_FILE)" &> $PRODUCT_HOME/cms_stackdump.txt &
    echo -n $"Stopping $PROGNAME: "
    # stop it here, often "killproc $PROGNAME"
    killproc -p $PID_FILE -d 3 $PROGNAME >/dev/null 2>&1
    echo_success
    retval=$?
    echo
    if [ $retval -eq 0 ]; then
        rm -f $LOCK_FILE
    else
        rh_status_q || rm -f $LOCK_FILE
    fi
    cms_shutdown_cleanup
    return $retval
}

restart() {
    rh_status_q && stop
    start
}

reload() {
    restart
}

force_reload() {
    restart
}

rh_status() {
    # run checks to determine if the service is running or use generic status
    status -p $PID_FILE $PROGNAME
    retval=$?
    if [ $retval -ne 0 ]; then
        pid=$(ps axw | grep "[D]program.name=$PROGNAME" | sed -e 's/^\s*//' | cut -d' ' -f1)
        if [ ! -z "$pid" ]; then
            echo $pid > $PID_FILE
            touch $LOCK_FILE
            rh_status
            return $?
        fi
    fi
    return $retval
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$2" in
    -v)
        VERBOSE_OUT=true
        ;;
esac

case "$1" in
    start)
        rh_status_q && rh_status && exit 0
        $1
        ;;
    stop)
        rh_status_q || rh_status || exit 0
        $1
        ;;
    restart)
        rh_status_q
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
        restart
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
        exit 2
esac
exit $?