#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

if [ -z "$1" ]
then
	echo "Invalid argument [$1];"
	echo "Usage: Only start | stop | restart | version, are supported."
	exit;
fi
action=$1
action=`echo $action | tr '[:lower:]' '[:upper:]'`
realScriptPath=`readlink -f $0`
realScriptDir=`dirname $realScriptPath`
RANGER_KMS_DIR=`(cd $realScriptDir; pwd)`
RANGER_KMS_EWS_DIR=${RANGER_KMS_DIR}/ews
RANGER_KMS_EWS_CONF_DIR="${RANGER_KMS_EWS_DIR}/webapp/WEB-INF/classes/conf"
RANGER_KMS_EWS_LIB_DIR="${RANGER_KMS_EWS_DIR}/webapp/WEB-INF/classes/lib"

JAVA_OPTS=" ${JAVA_OPTS} -XX:MaxPermSize=256m -Xmx1024m -Xms1024m "

if [ -f ${RANGER_KMS_DIR}/ews/webapp/WEB-INF/classes/conf/java_home.sh ]; then
        . ${RANGER_KMS_DIR}/ews/webapp/WEB-INF/classes/conf/java_home.sh
fi

for custom_env_script in `find ${RANGER_KMS_DIR}/ews/webapp/WEB-INF/classes/conf/ -name "ranger-kms-env*"`; do
        if [ -f $custom_env_script ]; then
                . $custom_env_script
        fi
done

if [ "$JAVA_HOME" != "" ]; then
        export PATH=$JAVA_HOME/bin:$PATH
fi

cd ${RANGER_KMS_EWS_DIR}

if [ -z "${RANGER_KMS_LOG_DIR}" ]
then
        RANGER_KMS_LOG_DIR=${RANGER_KMS_EWS_DIR}/logs
fi


PROC_NAME=proc_rangerkms
export PROC_NAME

START_CLASS_NAME="org.apache.ranger.server.tomcat.EmbeddedServer"

STOP_CLASS_NAME="org.apache.ranger.server.tomcat.StopEmbeddedServer"

#KMS_CONFIG_FILENAME=kms_webserver.properties
KMS_CONFIG_FILENAME=ranger-kms-site.xml

TOMCAT_LOG_DIR=${RANGER_KMS_LOG_DIR}

TOMCAT_LOG_FILE=${TOMCAT_LOG_DIR}/catalina.out
TOMCAT_STOP_LOG_FILE=${TOMCAT_LOG_DIR}/stop_catalina.out

if [ ! -d ${TOMCAT_LOG_DIR} ]
then
	mkdir -p ${TOMCAT_LOG_DIR}
fi

KMS_CONF_DIR=${RANGER_KMS_EWS_DIR}/webapp/WEB-INF/classes/conf
pidf="/var/run/ranger_kms/rangerkms.pid"
JAVA_OPTS="${JAVA_OPTS} -Dcatalina.base=${RANGER_KMS_EWS_DIR} -Dkms.config.dir=${KMS_CONF_DIR} -Dkms.log.dir=${TOMCAT_LOG_DIR} -cp ${RANGER_KMS_EWS_CONF_DIR}:${RANGER_KMS_EWS_LIB_DIR}/*:${RANGER_KMS_EWS_DIR}/webapp/lib/*:${JAVA_HOME}/lib/*:${RANGER_HADOOP_CONF_DIR}/*:$CLASSPATH "
createRangerKMSPid () {
	SLEEP_TIME_AFTER_START=5
	nohup java -D${PROC_NAME} ${JAVA_OPTS} ${START_CLASS_NAME} ${KMS_CONFIG_FILENAME} > ${TOMCAT_LOG_FILE} 2>&1 &
	VALUE_OF_PID=$!
	echo "Starting Apache Ranger KMS Service"
	sleep $SLEEP_TIME_AFTER_START
	if ps -p $VALUE_OF_PID > /dev/null
	then
		echo $VALUE_OF_PID > ${pidf}
		chown ranger ${pidf}
		chmod 660 ${pidf}
		pid=`cat $pidf`
		echo "Apache Ranger KMS Service with pid ${pid} has started."
	else
		echo "Apache Ranger KMS Service failed to start"
	fi
	exit ;
}
killRangerKMSPid () {
	WAIT_TIME_FOR_SHUTDOWN=2
	NR_ITER_FOR_SHUTDOWN_CHECK=15
	if [ -f "$pidf" ] ; then
		pid=`cat $pidf` > /dev/null 2>&1
		echo "Found Apache Ranger KMS Service with pid $pid, Stopping..."
		nohup java ${JAVA_OPTS} ${STOP_CLASS_NAME} ${KMS_CONFIG_FILENAME} > ${TOMCAT_STOP_LOG_FILE} 2>&1
		for ((i=0; i<$NR_ITER_FOR_SHUTDOWN_CHECK; i++))
		do
			sleep $WAIT_TIME_FOR_SHUTDOWN
			if ps -p $pid > /dev/null ; then
				echo "Shutdown in progress. Will check after $WAIT_TIME_FOR_SHUTDOWN secs again.."
				continue;
			else
				break;
			fi
		done
		# if process is still around, use kill -9
		if ps -p $pid > /dev/null ; then
			echo "Initial kill failed, getting serious now..."
			kill -9 $pid
		fi
		sleep 1 # Give kill -9 sometime to "kill"
		if ps -p $pid > /dev/null ; then
			echo "Wow, even kill -9 failed, giving up! Sorry.."
		else
			rm -rf $pidf
			echo "Apache Ranger KMS Service with pid ${pid} has been stopped."
		fi
	else
		echo "Apache Ranger KMS Service is not running"
	fi
}
if [ "${action}" == "START" ]; then
	if [ -f "$pidf" ] ; then
		pid=`cat $pidf`
		if  ps -p $pid > /dev/null
		then
			echo "Apache Ranger KMS Service is already running [pid={$pid}]"
			exit 1
		else
			rm -rf $pidf
			createRangerKMSPid
		fi
	else
		createRangerKMSPid
	fi
elif [ "${action}" == "STOP" ]; then
	killRangerKMSPid
	exit
elif [ "${action}" == "RESTART" ]; then
	echo "Restarting Apache Ranger KMS Service"
	killRangerKMSPid
	createRangerKMSPid
	exit
elif [ "${action}" == "VERSION" ]; then
	( cd ${RANGER_KMS_LIB_DIR} ; java -cp ranger-util-*.jar org.apache.ranger.common.RangerVersionInfo )
	exit
else
        echo "Invalid argument [$1];"
        echo "Usage: Only start | stop | restart | version, are supported."
        exit;
fi
