#!/usr/bin/perl -w

use strict;
use Proc::ProcessTable;
use DBI;
use Time::Format qw(%time);

my $debug = '0';

############## Database Configuration 
# $ENV{ORACLE_HOME} Path to oracle installation
# $dbuser oracle account used to connect to oracle 
# $dbpass oracle password for account 
# @db = qw( ow06adm ...) tnsname of database to check

$ENV{ORACLE_HOME} = '/opt/oracle/product/8.1.7';
my $dbuser = 'db_username';
my $dbpass = 'db_password';
my @db = qw( instance1 );

##################### Check the DB
# This should return true to the cluster
# even when a DB is down. The reason for this is 
# becasue the Application will exit if the DB is not
# Online. This is to trick the cluster

#logit('Start JAVA Monitor');

foreach my $db (@db)  {
	my $result = check_db($db);
	if($result) {
		foreach (@$result) {
			if ( @$_[0] =~ /^\bOPEN\b$/ ) {
				debug($db,'OK');
			} else {
				debug($db,'DOWN');
				logit("ORACLE $db down, but monitor should be true");
				exit 0;
			}
		}
	} else {
		logit("ORACLE $db down, but should be true");
		exit 0;
	} 
}

##################### Check the Processes
# Inorder for the monitor to be fast we take one snapshot 
# of the proc table and use for remaining checks. However 
# there is a risk that during the check a process could fail
# therefore this is not considered a accurate HA script.
# To ensure that each check rechecks the proc table comment the 
# Following Line and uncomment the same line in the check_proc
# sub routine.

my $t = new Proc::ProcessTable;

##################### Check the JAVA APP Processes
# If the JAVA_APP1 process is down then inform the 
# cluster that there is a fault. This is done
# with the exit code 100 (For complete failure).

unless (&check_proc('java -server -Djava_app1','3000')) {
	logit('JAVA APP 1 Offline OLY monitor should return false');
	exit 100;
}

#logit('End JAVA Monitor');

sub check_proc {
	my ($proc,$uid) = @_;
	my $pid;
	#my $t = new Proc::ProcessTable;
	foreach my $p ( @{$t->table} ){
   	unless($p->cmndline =~ /\b$proc\b/ && $p->uid =~ /$uid/) {
			next;
		}
		$pid = $p->pid;
		debug($proc,'OK');
	}

	unless ($pid) {
		debug($proc,'DOWN');
		return 0;
	}
}

sub check_db {
	my ($db) = shift;
	my $dbh = DBI->connect("dbi:Oracle:$db", $dbuser, $dbpass, { 
			RaiseError => 0,
			AutoCommit => 1,
			PrintError => 0 });  

	unless ( $dbh ) {
		#warn "Could not connect to $db: $DBI::errstr\n" ;
		return 0;
	}

	my $sth = $dbh->prepare("select status from v\$instance");
	$sth->execute;
	my $row = $sth->fetchall_arrayref;
	$sth->finish;
	$dbh->disconnect;
	return $row;
}

sub debug {
	my ($foo,$bar) = @_;
	printf("%-22s %-22s %-5s\n",$time{'dd/mm/yy hh:mm:ss.mmm'},$foo,$bar) if ($debug);
}

sub logit {
	my $message = shift;
	system("/usr/bin/logger -p daemon.notice -t Cluster.oly-java $message");
}
