#!/bin/bash

# This is a simple example of wsrep notification script (wsrep_notify_cmd).
# It will create 'wsrep' schema and two tables in it: 'membeship' and 'status'
# and fill them on every membership or node status change.
#
# Edit parameters below to specify the address and login to server.

DB=0
LOCKFILE="/var/lib/mysql/wsrep_notify.lock"

USER=root
HOST=127.0.0.1
PORT=3306

TIMEOUT=10
RETRY=30
SLEEP=1

SCHEMA="wsrep"
MEMB_TABLE="${SCHEMA}.membership"
STATUS_TABLE="${SCHEMA}.status"

BEGIN="
SET wsrep_on=0;
DROP SCHEMA IF EXISTS ${SCHEMA};
CREATE SCHEMA ${SCHEMA};
CREATE TABLE IF NOT EXISTS ${MEMB_TABLE} (
    idx  INT UNIQUE PRIMARY KEY,
    uuid CHAR(40) UNIQUE, /* node UUID */
    name VARCHAR(32),     /* node name */
    addr VARCHAR(256)     /* node address */
) ENGINE=MEMORY;
CREATE TABLE IF NOT EXISTS ${STATUS_TABLE} (
    size   INT,      /* component size   */
    idx    INT,      /* this node index  */
    status CHAR(16), /* this node status */
    uuid   CHAR(40), /* cluster UUID */
    prim   BOOLEAN   /* if component is primary */
) ENGINE=MEMORY;
BEGIN;
DELETE FROM ${MEMB_TABLE};
DELETE FROM ${STATUS_TABLE};
"
END="COMMIT;"


configuration_change() {
    echo "${BEGIN};"

    local idx=0

    for NODE in $(echo ${MEMBERS} | sed s/,/\ /g)
    do
        echo "INSERT INTO ${MEMB_TABLE} VALUES ( ${idx}, "
        # Don't forget to properly quote string values
        echo "'${NODE}'" | sed  s/\\//\',\'/g
        echo ");"
        idx=$(( ${idx} + 1 ))
    done

    echo "INSERT INTO ${STATUS_TABLE} VALUES(${idx}, ${INDEX}, '${STATUS}', '${CLUSTER_UUID}', ${PRIMARY});"

    echo "${END}"
}

status_update() {
    echo "SET wsrep_on=0; BEGIN; UPDATE ${STATUS_TABLE} SET status='${STATUS}'; COMMIT;"
}

mysql_background_loop() {
	MCOM=$1
	if [ "x${MCOM}" != "x" ]; then
		MRETRY=$2
		[ "x${MRETRY}" = "x" ] && MRETRY=30 || :
		MSLEEP=$3
		[ "x${MSLEEP}" = "x" ] && MSLEEP=1 || :
		MCNT=0
		while [ ${MCNT} -lt ${MRETRY} ]; do
			RV=1
			if [ "${MCOM}" = "configuration_change" -o -f "${LOCKFILE}" ]; then
				${MCOM} > /tmp/wsrep_notify.$$
				COMDATA="`cat /tmp/wsrep_notify.$$`"
				echo -e "${COMDATA}" | mysql -B --connect-timeout=${TIMEOUT} -u${USER} -h${HOST} -P${PORT} > /tmp/wsrep_notify_mysql.$$ 2>&1
				RV=$?
				RESDATA="`cat /tmp/wsrep_notify_mysql.$$`"
				if [ ${DB} -gt 0 ]; then echo "`date`: ${RV}: ${COMDATA} | mysql --connect-timeout=${TIMEOUT} -B -u${USER} -h${HOST} -P${PORT}: STATUS ${STATUS} - UUID ${CLUSTER_UUID} - PRIMARY ${PRIMARY} - INDEX ${INDEX} - MEMBERS ${MEMBERS} : ${RESDATA}" >> /tmp/wsn.out; fi
				if [ -f "/tmp/wsrep_notify.$$" ]; then rm -f /tmp/wsrep_notify.$$; fi
				if [ -f "/tmp/wsrep_notify_mysql.$$" ]; then rm -f /tmp/wsrep_notify_mysql.$$; fi
			fi
			if [ ${RV} -eq 0 ]; then
				MCNT=${MRETRY}
				if [ "${MCOM}" = "configuration_change" ]; then
					WCNT=`echo "SET wsrep_on=0; SHOW DATABASES LIKE 'wsrep';" | mysql -B --connect-timeout=${TIMEOUT} -u${USER} -h${HOST} -P${PORT} 2>/dev/null | wc -l`
					if [ ${WCNT} -gt 0 ]; then touch ${LOCKFILE}; fi
				fi
			else
				let MCNT=${MCNT}+1
				sleep ${MSLEEP}
			fi
		done
	fi
}

COM=status_update # not a configuration change by default

while [ $# -gt 0 ]
do
    case $1 in
    --status)
        STATUS=$2
        shift
        ;;
    --uuid)
        CLUSTER_UUID=$2
        shift
        ;;
    --primary)
        [ "$2" = "yes" ] && PRIMARY="1" || PRIMARY="0"
        COM=configuration_change
        shift
        ;;
    --index)
        INDEX=$2
        shift
        ;;
    --members)
        MEMBERS=$2
        shift
        ;;
    esac
    shift
done

# Undefined means node is shutting down
WCNT=0
if [ "${STATUS}" = "Undefined" ]; then
	COM=""
else
	WCNT=`echo "SET wsrep_on=0; SHOW DATABASES LIKE 'wsrep';" | mysql -B --connect-timeout=${TIMEOUT} -u${USER} -h${HOST} -P${PORT} 2>/dev/null | wc -l`
fi
if [ ${WCNT} -eq 0 ]; then rm -f ${LOCKFILE}; fi

mysql_background_loop "${COM}" "${RETRY}" "${SLEEP}" &

exit 0
#
