#!/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."
	echo "For KMSMetric Usage: metric -type  hsmenabled | encryptedkey | encryptedkeybyalgorithm"
	exit;
fi
action=$1
arg2=$2
arg3=$3
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

if [ -z "${RANGER_KMS_PID_NAME}" ]
then
        RANGER_KMS_PID_NAME=rangerkms.pid
fi

if [ -z "${RANGER_KMS_PID_DIR_PATH}" ]
then
	RANGER_KMS_PID_DIR_PATH=/var/run/ranger_kms
fi
if [ ! -d "${RANGER_KMS_PID_DIR_PATH}" ]
then
	mkdir -p  $RANGER_KMS_PID_DIR_PATH
	chmod 660 $RANGER_KMS_PID_DIR_PATH
fi
# User can set their own pid path using RANGER_KMS_PID_DIR_PATH and
# RANGER_KMS_PID_NAME variable before calling the script. The user can modify
# the value of the RANGER_KMS_PID_DIR_PATH in ranger-kms-env-piddir.sh to
# change pid path and set the value of RANGER_KMS_PID_NAME to change the
# pid file.
pidf=${RANGER_KMS_PID_DIR_PATH}/${RANGER_KMS_PID_NAME}

if [ -z "${KMS_USER}" ]
then
	KMS_USER=kms
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
SERVER_NAME=rangerkms
JAVA_OPTS="${JAVA_OPTS} ${DB_SSL_PARAM} -Duser=${USER} -Dhostname=${HOSTNAME} -Dservername=${SERVER_NAME} -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 ${KMS_USER} ${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
}
metric(){
  if [ "$JAVA_HOME" == "" ]; then
    echo "[E] JAVA_HOME environment variable not defined, aborting Apache Ranger KMS metric collection" 1>&2;
    exit 1;
  fi
	java  ${JAVA_OPTS} org.apache.hadoop.crypto.key.kms.server.KMSMetricUtil ${arg2} ${arg3} 2>/dev/null
}
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}" == "METRIC" ]; then
	metric;
	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."
        echo "For KMSMetric Usage: metric -type  hsmenabled | encryptedkey | encryptedkeybyalgorithm"
        exit;
fi
