#!/bin/bash
#---- {COPYRIGHT-TOP} ----
# Licensed Materials - Property of IBM
# 
#
# (C) Copyright IBM Corp. 2000, 2008
#
# US Government Users Restricted Rights - Use, duplication, or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#---- {COPYRIGHT-END} ----
# author: Faheem Hussain

#Reads the incorrectly logged in users from the "lot" table 
#and fixes them by updating the logout_time and logout_method
#values for these rows with the last heartbeat time from the 
#jhb table if found.
#------------------------------------------------------------------
if [ ! -n "$TOP" ]; then
	echo "Please setup the environment for WPC first and then run this script again."
	exit 1
fi

curdir="`pwd`"
${ECHO} "DIRECTORY NOW IS $curdir"

DIR_LOGS=${TOP}/logs
DIR_DEFAULT_LOGS=$DIR_LOGS/default

if [ ! -d $DIR_DEFAULT_LOGS ]; then
	${MKDIR} -p $DIR_DEFAULT_LOGS
fi
DEFAULT_DB_LOG=$DIR_DEFAULT_LOGS/db.log
if [ ! -f $DEFAULT_DB_LOG ]; then
	${TOUCH} $DEFAULT_DB_LOG
fi

TEMP_LOG_FILE=$DIR_LOGS/fixing_logins.log
if [ ! -f $TEMP_LOG_FILE ]; then
	${TOUCH} $TEMP_LOG_FILE
fi
${ECHO}  >> $TEMP_LOG_FILE
${ECHO} "=====Fixing hung logins====" >> $TEMP_LOG_FILE
${ECHO}  $(date) >> $TEMP_LOG_FILE
${ECHO}  >> $TEMP_LOG_FILE

TEMP_LOGINS_FILE=$DIR_LOGS/hung_logins.txt
if [ ! -f $TEMP_LOGINS_FILE ]; then
	${TOUCH} $TEMP_LOGINS_FILE
fi
TEMP_HEARTBEAT_TIME_FILE=$DIR_LOGS/last_heartbeat_time.txt
if [ ! -f $TEMP_HEARTBEAT_TIME_FILE ]; then
	${TOUCH} $TEMP_HEARTBEAT_TIME_FILE
fi

INCORRECT_LOGINS_COUNT="0"
MSG_NO_INCORRECT_LOGINS="No hung login(s) found!"
LOGOUT_TIME=""


# get src connection descriptor
. ${TOP}/src/db/schema/util/set_db.sh --confirm_db=no

TOP_SQL="
set sqlnumber off;
set heading off;
set pagesize 0;
set linesize 10000;
set echo off;
set show off;
set feedback off;
set trimspool on;
set term off;
"

#--------------------------------------------------
#-- Get the lot rows for correction (oracle)

ora_getHungLogins ()
{
${ECHO}
${ECHO}
${ECHO} ===============================================
${ECHO} Getting the hung login records
${ECHO} ===============================================
${ECHO}  >> $TEMP_LOG_FILE
${ECHO} "=====Finding hung login records====" >> $TEMP_LOG_FILE
${ECHO}  $(date) >> $TEMP_LOG_FILE
${ECHO}  >> $TEMP_LOG_FILE

    ${CCD_SQLPLUS} ${CONNECTION} <<EOF >> $TEMP_LOG_FILE 2>&1
    $TOP_SQL
    spool $TEMP_LOGINS_FILE;
    select lot_session_id
    from tsec_lot_login_times
    where lot_logout_time is null;
    spool off;
EOF
}

db2_getHungLogins ()
{
${ECHO}
${ECHO}
${ECHO} ===============================================
${ECHO} Getting the hung login records
${ECHO} ===============================================
${ECHO}  >> $TEMP_LOG_FILE
${ECHO} "=====Finding hung login records====" >> $TEMP_LOG_FILE
${ECHO}  $(date) >> $TEMP_LOG_FILE
${ECHO}  >> $TEMP_LOG_FILE

		if [ ${CCD_DB} = "db2" ] && [ "${PLATFORM}" != "WINDOWS" ] && [ "${PLATFORM}" != "CYGWIN" ]; then  
			${CCD_SQLPLUS_LOGIN} ${CONNECTION} >> $TEMP_LOG_FILE 2>&1
			db2 "select lot_session_id from tsec_lot_login_times where lot_logout_time is null" > $TEMP_LOGINS_FILE
			${DB_DISCONNECT}
		else
			${CCD_SQLPLUS} ${CONNECTION} <<EOF >> $TEMP_LOG_FILE 2>&1 
			db2 "select lot_session_id from tsec_lot_login_times where lot_logout_time is null" > $TEMP_LOGINS_FILE
			${DB_DISCONNECT}
EOF
		fi
}
#---------------------------------------------------------------
#-- Get the last heartbeat time of appServer if available(oracle)

ora_getLastHeartBeat ()
{
${ECHO}
${ECHO}
${ECHO} =====================================================
${ECHO} Getting last heartbeat time of appServer if available
${ECHO} =====================================================
${ECHO}  >> $TEMP_LOG_FILE
${ECHO} "=====Finding last heartbeat time of appServer====" >> $TEMP_LOG_FILE
${ECHO}  $(date) >> $TEMP_LOG_FILE
${ECHO}  >> $TEMP_LOG_FILE
    ${CCD_SQLPLUS} ${CONNECTION} <<EOF  >> $TEMP_LOG_FILE 2>&1
    $TOP_SQL
    spool $TEMP_HEARTBEAT_TIME_FILE;
    select TO_CHAR(jhb_heartbeat , 'yyyy/mm/dd:HH:mi:ss')
    from tutl_jhb_jvm_heartbeat
    where jhb_jvm_type='appsvr';
    spool off;
EOF
}

db2_getLastHeartBeat ()
{
${ECHO}
${ECHO}
${ECHO} =====================================================
${ECHO} Getting last heartbeat time of appServer if available
${ECHO} =====================================================
${ECHO}  >> $TEMP_LOG_FILE
${ECHO} "=====Finding last heartbeat time of appServer====" >> $TEMP_LOG_FILE
${ECHO}  $(date) >> $TEMP_LOG_FILE
${ECHO}  >> $TEMP_LOG_FILE
		if [ ${CCD_DB} = "db2" ] && [ "${PLATFORM}" != "WINDOWS" ] && [ "${PLATFORM}" != "CYGWIN" ]; then  
			${CCD_SQLPLUS_LOGIN} ${CONNECTION} >> $TEMP_LOG_FILE 2>&1
			db2 "select jhb_heartbeat from tutl_jhb_jvm_heartbeat where jhb_jvm_type='appsvr'" > $TEMP_HEARTBEAT_TIME_FILE
			${DB_DISCONNECT}
		else
			${CCD_SQLPLUS} ${CONNECTION} <<EOF >> $TEMP_LOG_FILE 2>&1
			db2 "select jhb_heartbeat from tutl_jhb_jvm_heartbeat where jhb_jvm_type='appsvr'" > $TEMP_HEARTBEAT_TIME_FILE
			${DB_DISCONNECT}
EOF
		fi
}


#--------------------------------------------------
#-- Update the incorrect login records for oracle

ora_updateHungLoginRecords ()
{
${ECHO}
${ECHO}
${ECHO} =====================================================
${ECHO} "Updating hung login record(s)"
${ECHO} =====================================================
${ECHO}  >> $TEMP_LOG_FILE
${ECHO} "=====Updating hung login records====" >> $TEMP_LOG_FILE
${ECHO}  $(date) >> $TEMP_LOG_FILE
${ECHO}  >> $TEMP_LOG_FILE
    ${CCD_SQLPLUS} ${CONNECTION} <<EOF >> $TEMP_LOG_FILE 2>&1
    $TOP_SQL;
    update tsec_lot_login_times set lot_logout_time=TO_DATE('$LOGOUT_TIME' , 'yyyy/mm/dd:HH:mi:ss'),lot_logout_method='T' 
    where lot_logout_time is null;
    spool off;
EOF
${ECHO} Fixed the hung logins. Please verify by logging into WPC!
}

#--------------------------------------------------
#-- Update the incorrect login records for db2

db2_updateHungLoginRecords ()
{
${ECHO}
${ECHO}
${ECHO} =====================================================
${ECHO} "Updating hung login record(s)"
${ECHO} =====================================================
${ECHO}  >> $TEMP_LOG_FILE
${ECHO} "=====Updating hung login records====" >> $TEMP_LOG_FILE
${ECHO}  $(date) >> $TEMP_LOG_FILE
${ECHO}  >> $TEMP_LOG_FILE
		if [ ${CCD_DB} = "db2" ] && [ "${PLATFORM}" != "WINDOWS" ] && [ "${PLATFORM}" != "CYGWIN" ]; then  
			${CCD_SQLPLUS_LOGIN} ${CONNECTION} >> $TEMP_LOG_FILE 2>&1
			db2 "update tsec_lot_login_times set lot_logout_time='$LOGOUT_TIME',lot_logout_method='T' where lot_logout_time is null"
			${DB_DISCONNECT}
		else
			${CCD_SQLPLUS} ${CONNECTION} <<EOF >> $TEMP_LOG_FILE 2>&1
			db2 "update tsec_lot_login_times set lot_logout_time='$LOGOUT_TIME',lot_logout_method='T' where lot_logout_time is null"
			${DB_DISCONNECT}
EOF
		fi
		${ECHO} Fixed the hung logins. Please verify by logging into WPC!
}
#--------------------------------------------------
#-- Cleanup the temporary files

cleanup()
{
${ECHO} Cleaning up the temporary files...
${ECHO} Check $DEFAULT_DB_LOG for more details
${ECHO} "====Cleaning up====" >> $DEFAULT_DB_LOG 2>&1
${CAT} $TEMP_LOG_FILE >> $DEFAULT_DB_LOG 2>&1
${RM} $TEMP_LOG_FILE
${RM} $TEMP_LOGINS_FILE
${RM} $TEMP_HEARTBEAT_TIME_FILE
${ECHO}   >> $DEFAULT_DB_LOG 2>&1
${ECHO} ====DONE==== >> $DEFAULT_DB_LOG 2>&1
${ECHO} 
${ECHO} DONE
${ECHO} 
}
#--------------------------------------------------
#-- Run fixing procedures for oracle

ora_fixHungLogins () 
{
	${ECHO}
	${ECHO}
	${ECHO} =====================================================
	${ECHO} Trying to fix hung logins for Oracle
	${ECHO} =====================================================

	ora_getHungLogins
	${CAT} $TEMP_LOGINS_FILE >> $TEMP_LOG_FILE 2>&1
	INCORRECT_LOGINS_COUNT=`${GREP} -c '$' $TEMP_LOGINS_FILE`
	if [ "$INCORRECT_LOGINS_COUNT" != "0" ]
	then
		${ECHO} 
		${ECHO} "Found $INCORRECT_LOGINS_COUNT incorrect login record[s]"
		${ECHO}    >> $TEMP_LOG_FILE 2>&1
		${ECHO} "Found $INCORRECT_LOGINS_COUNT incorrect login record[s]" >> $TEMP_LOG_FILE 2>&1
		ora_getLastHeartBeat
		${CAT} $TEMP_HEARTBEAT_TIME_FILE >> $TEMP_LOG_FILE 2>&1
		LOGOUT_TIME=`${CAT} $TEMP_HEARTBEAT_TIME_FILE`
		if [ -n "$LOGOUT_TIME" ]; then
			${ECHO}
			${ECHO} "Found the time of the last appsvr hearbeat"
			${ECHO} $LOGOUT_TIME
			${ECHO} "Using last heartbeat time to fix hung logins"
			${ECHO}  
			${ECHO} "Found the time of the last appsvr hearbeat" >> $TEMP_LOG_FILE 2>&1
			${ECHO} $LOGOUT_TIME >> $TEMP_LOG_FILE 2>&1
			${ECHO} "Using last heartbeat time to correct hung logins" >> $TEMP_LOG_FILE 2>&1
			ora_updateHungLoginRecords
		else
			LOGOUT_TIME=$(date "+%Y/%m/%d:%T");
			${ECHO}
			${ECHO} Last heartbeat time of the appSvr not found.
			${ECHO} "Using current time $LOGOUT_TIME to update incorrect logins"
			${ECHO}   >> $TEMP_LOG_FILE 2>&1
			${ECHO} "Using current time $LOGOUT_TIME to update incorrect logins" >> $TEMP_LOG_FILE 2>&1
			ora_updateHungLoginRecords
		fi

	else
		${ECHO} $MSG_NO_INCORRECT_LOGINS
		${ECHO}   >> $TEMP_LOG_FILE 2>&1
		${ECHO} $MSG_NO_INCORRECT_LOGINS >> $TEMP_LOG_FILE 2>&1
		cleanup
		exit 1
	fi
	
}

db2_fixHungLogins () 
{
	${ECHO}
	${ECHO}
	${ECHO} =====================================================
	${ECHO} Trying to fix hung logins for DB2
	${ECHO} =====================================================
	db2_getHungLogins
	${CAT} $TEMP_LOGINS_FILE >> $TEMP_LOG_FILE 2>&1
	INCORRECT_LOGINS_COUNT=`${GREP} -c '^[[:space:]]* [[:digit:]][[:digit:]]*[[:space:]]*$' $TEMP_LOGINS_FILE`
	if [ "$INCORRECT_LOGINS_COUNT" != "0" ]
	then
		${ECHO} 
		${ECHO} "Found $INCORRECT_LOGINS_COUNT incorrect login record(s)"
		${ECHO} 
		${ECHO} "Found $INCORRECT_LOGINS_COUNT incorrect login record(s)" >> $TEMP_LOG_FILE 2>&1
		db2_getLastHeartBeat
		${CAT} $TEMP_HEARTBEAT_TIME_FILE >> $TEMP_LOG_FILE 2>&1
		LOGOUT_TIME=`${GREP} '^[[:space:]]*[[:digit:]]\{4\}-[[:digit:]]\{2\}-[[:digit:]]\{2\}.*$' $TEMP_HEARTBEAT_TIME_FILE | ${CUT} -f1`

		if [ -n "$LOGOUT_TIME" ]; then
			${ECHO}
			${ECHO} "Found the time of the last appsvr hearbeat"
			${ECHO} $LOGOUT_TIME
			${ECHO} "Using last heartbeat time to correct hung logins"
			${ECHO}  
			${ECHO} "Found the time of the last appsvr hearbeat" >> $TEMP_LOG_FILE 2>&1
			${ECHO} $LOGOUT_TIME >> $TEMP_LOG_FILE 2>&1
			${ECHO} "Using last heartbeat time to correct hung logins" >> $TEMP_LOG_FILE 2>&1
			db2_updateHungLoginRecords
		else
			LOGOUT_TIME=$(date "+%Y-%m-%d-%H.%M.%S.000000");
			${ECHO}
			${ECHO} Last heartbeat time of the appSvr not found.
			${ECHO} "Using current time $LOGOUT_TIME to update incorrect logins"
			${ECHO}   >> $TEMP_LOG_FILE 2>&1
			${ECHO} "Using current time $LOGOUT_TIME to update incorrect logins" >> $TEMP_LOG_FILE 2>&1
			db2_updateHungLoginRecords
		fi

	else
		${ECHO} $MSG_NO_INCORRECT_LOGINS
		${ECHO}   >> $TEMP_LOG_FILE 2>&1
		${ECHO} $MSG_NO_INCORRECT_LOGINS >> $TEMP_LOG_FILE 2>&1
		cleanup
		exit 1
	fi
	
}
${ECHO}
${ECHO} "=================================================="
${ECHO} "=== All WPC users are required to be "
${ECHO} "=== logged out before running this script. "
${ECHO}
${ECHO} "Are you sure no users are logged in to WPC ? (y/n)"
read res

if [ "$res" = "y" ]
then
	if [ "$CCD_DB" = "oracle" ] ; then
		${ECHO} "========================"
		${ECHO} "====CCD_DB is oracle===="
		${ECHO} "========================"
		ora_fixHungLogins
	elif  [ "$CCD_DB" = "db2" ]; then 
		${ECHO} "========================"
		${ECHO} "=====CCD_DB is DB2======"
		${ECHO} "========================"
		db2_fixHungLogins
	else
		${ECHO} 
		${ECHO} "CCD_DB can be either oracle or db2!!!!"
		${ECHO} 
	fi
	
else
	${ECHO} "No action was taken. Exiting the script!!!"
	${ECHO} "No action was taken. Exiting the script!!!" >> $TEMP_LOG_FILE 2>&1
fi
cleanup
exit 1
