#!/bin/sh
#
#
#*************************************************

#Copyright (c) KylinSoft Co., Ltd. [2021-2025]. All rights reserved.
#File name: mqm
#Author: XuXiaojuan
#Version: 1
#Description: Manages  Websphere MQ as Linux-HA resource 
#Date: 2023.12.28
#Others: 
#Function List: 
#1.mqm_status(): report whether the middleware queue manager is running
#2.mqm_monitor():report whether middleware queue manager seems to be working
#3.mqm_start():start the middleware
#4.mqm_stop():stop the middleware

#History: 
#1. Date: 2023.12.28 Author: XuXiaojuan Modification:add mqm ocf script

#*************************************************

#
# Include general OCF functions and variables (such as OCF return codes).
#
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs


#
# Function that displays the usage of this script.
#
mqm_usage() {
	methods=`mqm_methods`
	methods=`echo $methods | tr ' ' '|'`

	echo "
	usage: $0 ($methods)

	$0 manages Websphere MQ as an High-Availability resource.

	The 'start' operation starts the middleware.
	The 'stop' operation stops the middleware.
	The 'status' operation reports whether the middleware queue manager is running
	The 'monitor' operation reports whether the middleware queue manager seems to be working
	The 'methods' operation lists the methods $0 supports
	The 'usage' operation displays this text
	The 'meta-data' operation returns the meta-data (in XML) of this resource script
    "
}


#
# Function that displays the possible methods this script supports.
#
mqm_methods() {
	echo " 
	start
	stop
	status
	monitor
	methods
	usage
	meta-data
	"
}


#
# Function that displays the meta-data of this OCF resource agent.
#
mqm_meta_data() {
    cat <<-!
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="mqm">
<version>1.0</version>


<longdesc lang="en">
OCF resource agent to manage Websphere MQ as an High-Availability resource.
</longdesc>
<shortdesc lang="en">Manages Websphere MQ queue</shortdesc>

<parameters>

<parameter name="MQ_HOME" unique="0" required="1">
<longdesc lang="en">
Directory containing MQ
</longdesc>
<shortdesc lang="en">MQ installdir</shortdesc>
<content type="string" default="/opt/mqm" />
</parameter>

<parameter name="queuename" unique="0" required="1">
<longdesc lang="en">
The name of the queue manager to be managed
</longdesc>
<shortdesc lang="en">Queue manger name</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="stopsleeptime" unique="0" required="1">
<longdesc lang="en">
The time stop process need to sleep,maybe need change
</longdesc>
<shortdesc lang="en">The time stop process need to sleep,maybe need change</shortdesc>
<content type="string" default="3" />
</parameter>

</parameters>

<actions>
<action name="start" timeout="120" />
<action name="stop" timeout="120" />
<action name="status" timeout="60" />
<action name="monitor" depth="0" timeout="30" interval="30" />
<action name="meta-data" timeout="5" />
<action name="methods" timeout="5" />
<action name="usage" timeout="5" />
</actions>


</resource-agent>
!
}


#
# Function that either forwards log messages to the ocf_log function
# provided by heartbeat or simply prints them to standard out via echo.
# This is determined by setting the variable "mqmlogger" to "echo" or "ocf".
# The default for "mqmlogger" is "ocf".
#
mqm_log() {

	# Where should the passed log messages be passed to,
	# to the standard output via the echo command ("echo")
	# or to the ocf_log function provided by heartbeat ("ocf") ?
	# Default is "ocf".
	mqmlogger="ocf"

	# When the variable "mqmdebug" is not set to "true"
	# this function (mqm_log) will not print any info message
	# that has been forwarded to it!
	# This is done in order to spare if-statements within the 
	# other functions in this script and to centralize the decision
	# whether to have a chatty resource script or not... ;)
	# Nevertheless, error messages will always be printed!
	mqmdebug=false

	# Only continue if the two expected parameters 
	# are not empty and "mqmdebug" is set to "true"
	# or the message is of type "error".
	if [ $# -eq 2 -a -n "$1" -a -n "$2" ]; then
		if [ "$mqmdebug" = "true" -o "$1" = "error" ]; then
			case $mqmlogger in
				# Print messages to stdout via echo command.
				echo)
					echo "`date +'%b %d %H:%M:%S'`: [$1] $2";;
				# Pass messages to ocf_log function.
				ocf|*)
					ocf_log "$1" "$2";;
			esac
		fi
	fi		
}


#
# Function that prints the current values of important environment variables
# needed by the script and the IDS instance itself. The just mentioned variables are:
# - INFORMIXDIR
# - INFORMIXSERVER
# - ONCONFIG
# - PATH
# - LD_LIBRARY_PATH
#
mqm_debug() {
	mqm_log info "called mqm_debug"	

	mqm_log info "this script is run as user: `id`"
	mqm_log info "...in the current working directory: `pwd`"
}

#
# Function that start the mqm queue and reports any error that
# may occur while starting.
#
mqm_start() {

	mqm_log info "called mqm_start"
	
	# Get current status 
	mqm_status
	stat=$?
	case $stat in
		
		# MQ already running - exit with success.
		$OCF_SUCCESS)
			mqm_log info "mqm_start: The MQ queue manager already running: $stat"
			rc=$OCF_SUCCESS;;
	
		# instance in undefined state - exit with error.
		$OCF_ERR_GENERIC)
			mqm_log error "mqm_start: The MQ queue manager in undefined state: $stat"
			mqm_debug
			rc=$OCF_ERR_GENERIC;;	

		# MQ not running - try to start it.
		$OCF_NOT_RUNNING)
			mqm_log info "mqm_start: executing 'mqmstart' now..."	
			su - mqm -c "$OCF_RESKEY_MQ_HOME/bin/strmqm $OCF_RESKEY_queuename"
			stat=$?
			mqm_log info "mqm_start: done executing 'mqmstart': $stat"
			
			# The mqmstart command terminated successfully - check new state of MQ queue.
			if [ $stat -eq 0 ]; then
				# Initialize stat with failure exit status code.
				stat=$OCF_ERR_GENERIC
				# Endless loop that waits until mqm is completely online.
				# If mqm takes too long to achieve this or even hangs, 
				# the timeout settings of heartbeat will cancel the starting 
				# of the mqm resource and therefore terminate the loop.
				while [ $stat -ne $OCF_SUCCESS ]; do
					mqm_status
					stat=$?
				done
				# mqm is running now - success.
				mqm_log info "mqm_start: MQ queue mananger $OCF_RESKEY_queuename successfully started: $stat"
				rc=$OCF_SUCCESS
			# The mqmstart command terminated with an error - starting the MQ resource failed!
			else
				mqm_log error "mqm_start: starting MQ queue mananger $OCF_RESKEY_queuename failed: $stat"
				mqm_debug
				rc=$OCF_ERR_GENERIC			
			fi
			;;

		# Unexpected state - return OCF_ERR_UNIMPLEMENTED error.
		*) 
			mqm_log error "mqm_start: unexpected state returned from mqm_status: $stat"
			mqm_debug
			rc=$OCF_ERR_UNIMPLEMENTED;;				

	esac

	# Return exit status code.
	return $rc
}


#
# Function that stops the MQ queue manager and reports any error that
# may occur while stopping.
#
mqm_stop() {
	
	mqm_log info "called mqm_stop"

	mqm_status
	stat=$?

	case $stat in

        # mqm is not running - success stopping it.
        $OCF_NOT_RUNNING)
			mqm_log info "mqm_stop: MQ queue mananger $OCF_RESKEY_queuename is not running: $stat"
            rc=$OCF_SUCCESS;;

        # mqm instance is in an undefined state - exit with error.
        $OCF_ERR_GENERIC)
			mqm_log error "mqm_stop: MQ queue mananger $OCF_RESKEY_queuename in undefined state: $stat"
			mqm_debug
            rc=$OCF_ERR_GENERIC;;

        # mqm instance is running - try to stop it.
        $OCF_SUCCESS)
			mqm_log info "mqm_stop: running 'endmqm' now..."
			su - mqm -c "$OCF_RESKEY_MQ_HOME/bin/endmqm $OCF_RESKEY_queuename"
			stat=$?
			mqm_log info "mqm_stop: done running 'mqmstop' now: $stat"

			# The mqmstop command terminated successfully - check new state of the mqm.
			if [ $stat -eq 0 ]; then
				sleep $OCF_RESKEY_stopsleeptime
				mqm_status
                stat=$?
                # New state is: not running - success.
                if [ $stat -eq $OCF_NOT_RUNNING ]; then
					mqm_log info "mqm_stop: MQ queue mananger $OCF_RESKEY_queuename successfully stopped: $stat"
                    rc=$OCF_SUCCESS
                # New state is: running or even undefined - failure!
                else
					mqm_log error "mqm_stop: stopping MQ queue mananger $OCF_RESKEY_queuename failed: $stat"
                    mqm_debug
                    rc=$OCF_ERR_GENERIC
                fi
				
 			# The mqmstop command terminated with an error - stopping the mqm resource failed!
            else
				mqm_log error "mqm_stop: stopping MQ queue mananger $OCF_RESKEY_queuename failed: $stat"
                mqm_debug
                rc=$OCF_ERR_GENERIC
            fi
            ;;

		# Unexpected state - return OCF_ERR_UNIMPLEMENTED error.
        *)
			mqm_log error "mqm_stop: unexpected state returned from mqm_status: $stat"
			mqm_debug
            rc=$OCF_ERR_UNIMPLEMENTED;;
		
	esac

	# Return exit status code indicating whether mqm was successfully stopped or not.
	return $rc
}


mqm_status() {
	
	mqm_log info "called dspmq"

	# Get current status from the dspmq and store it.
	stat=`su - mqm -c "$OCF_RESKEY_MQ_HOME/bin/dspmq -m $OCF_RESKEY_queuename"`
	ret=$?
	if [ $ret -eq 0 ]; then
	    #status=`echo $stat|awk -F" " '{print $2}'|awk -F"(" '{print $2}'`
	    case $stat in
		    *"Ended"*)
			mqm_log info "mqm_status: mqm is not running: $stat"
                        rc=$OCF_NOT_RUNNING;;
		    *"Running"*)
			 mqm_log info "mqm_status: mqm is running: $stat"
                        rc=$OCF_SUCCESS;;
		    *"Quiescing"*)
			 mqm_log info "mqm_status: mqm is Quiescing: $stat"
			 sleep 3
			 rc=$OCF_NOT_RUNNING;;
		    *)
                        mqm_log error "mqm_status: mqmstatus is undefined1: $stat"
                        rc=$OCF_ERR_GENERIC;;
		esac

	else 
		mqm_log error "mqm_status: mqmstatus is undefined2: $stat"
                rc=$OCF_ERR_GENERIC

	fi

	
	# Return exit status code (ergo current status of the mqm instance) to caller
	return $rc
}


mqm_monitor() {
	
	mqm_log info "called mqm_monitor" 

	mqm_status
	stat=$?

	case $stat in

        # mqm is not running - monitoring failed.
        $OCF_NOT_RUNNING)
			mqm_log info "mqm_monitor: mqm is not running: $stat"
            rc=$OCF_NOT_RUNNING;;

        # mqm instance in an undefined state - exit with error.
        $OCF_ERR_GENERIC)
			mqm_log error "mqm_monitor: mqm in undefined state: $stat"
			mqm_debug
            rc=$OCF_ERR_GENERIC;;

        # mqm instance is running .
        $OCF_SUCCESS)
			mqm_log info "mqm_monitor: mqm is running"
                    	rc=$OCF_SUCCESS
            		;;

		# Unexpected state - return OCF_ERR_UNIMPLEMENTED error!
        *)
			mqm_log error "mqm_monitor: unexpected state returned from mqm_status: $stat"
			mqm_debug
            rc=$OCF_ERR_UNIMPLEMENTED;;
		
	esac

	# Return exit status code indicating whether mqm is running and functional or not.
	return $rc
}




###
#
# M A I N   S E C T I O N
#
###
case "$1" in
	usage)
		mqm_usage
		exit $?;;
	meta-data)
		mqm_meta_data
		exit $?;;
esac

case "$1" in

	start)	
		mqm_start
		exit $?;;

	stop)	
		mqm_stop
		exit $?;;

	status)	
		mqm_status
		exit $?;;

	monitor)	
		mqm_monitor
		exit $?;;

	methods)
		mqm_methods
		exit $?;;

	*)
		mqm_log error "mainsection: no or invalid command supplied: $1"
		exit $OCF_ERR_UNIMPLEMENTED;;

esac
#################mqm############################################################
