#!/usr/bin/perl -w use strict; use Safe; use warnings; use File::Spec; use File::Basename; my $cfgKey; my $cfgValue; my $cfg_key; my $rc = 0; my $append = ">>"; my $plFile = File::Spec->rel2abs( __FILE__); my ($file,$dir,$ext) = fileparse($plFile, qr/\.[^.]*/); my $propsFile = $dir."checkCLM.properties"; my $jtsCurlCmd = "NA"; my $qmCurlCmd = "NA"; my $ccmCurlCmd = "NA"; my $rmCurlCmd = "NA"; my $clmServerCMD = "NA"; my $clmServerProfileName = ""; my $clmServerPID = ""; my @pidFileElements; my $pidFileName = ""; my $pidFileFolder = ""; my $pidFileFullPath = ""; my $pidFileDirPath = ""; my $scfPath = ""; my $sbPath = ""; my $backSlashChar = "\\\\"; my $forwardSlashChar = "/"; my $stopRestartFlag = 0; my $jtsResponseCheckFlag = 0; my $qmResponseCheckFlag = 0; my $ccmResponseCheckFlag = 0; my $rmResponseCheckFlag = 0; my $curlCompletionMsg = ""; my $layout = "[%s] %s - %s\n"; my $logWriter = createLogger(); my %CFG = ( 'PUBLIC_URI_HOSTNAME' => 'clm uri', 'WAS_SERVER_PROFILE_PATH' => 'primary was server profile path', 'WAS_SERVICE_NAME' => 'server1', 'CONTEXT_ROOTS' => { 'CONTEXT_ROOT_JTS' => 'jts', 'CONTEXT_ROOT_RQM' => 'qm', 'CONTEXT_ROOT_RM' => 'rm/web', 'CONTEXT_ROOT_CCM' => 'ccm', 'CONTEXT_ROOT_ADMIN' => '/admin' }, 'PID_FILE_NAME' => 'PIDFILENAME', 'PID_FILE_FULL_PATH' => 'PIDFPATH', 'PID_FILE_DIR_PATH' => 'PIDSPATH', 'SERVER_BIN_PATH' => 'SBP', 'SERVER_CREDS_FILE_PATH' => 'SCFP', 'CLM_SERVER_PROFILE_NAME' => 'CSPN' ); my %levels = ( '0' => 'TRACE', '1' => 'DEBUG', '2' => 'INFO', '3' => 'WARN', '4' => 'ERROR', '5' => 'FATAL' ); sub new { my $self = {}; $self->{handle} = undef; $self->{level} = 0; bless($self); return $self; } sub DESTROY { my $self = shift; my $handle = $self->{handle}; close($handle); } sub createLogger { my ($self, $level, $name) = @_; my $logger = new(); $level = 'TRACE' if !defined($level); $name = sprintf("%s_%s.log", &getApplicationName(), substr(&getTS(), 0, 10)) if !defined($name); my $l_file = sprintf("%s", $name); if ($logger->initialize($l_file, $level) == 0) { return undef; } else { return $logger; } } sub getTS{ my @current_time = localtime(time); $current_time[5] += 1900; if ($current_time[4] + 1 < 10) { $current_time[4] = sprintf("0%d", $current_time[4] + 1); } else { $current_time[4] += 1; } if ($current_time[3] < 10) { $current_time[3] = sprintf("0%d", $current_time[3]); } if ($current_time[2] < 10) { $current_time[2] = sprintf("0%d", $current_time[2]); } if ($current_time[1] < 10) { $current_time[1] = sprintf("0%d", $current_time[1]); } if ($current_time[0] < 10) { $current_time[0] = sprintf("0%d", $current_time[0]); } my $timestamp = sprintf("%s-%s-%s.%s.%s.%s", $current_time[5], $current_time[4], $current_time[3], $current_time[2], $current_time[1], $current_time[0]); return $timestamp; } sub getApplicationName { return substr(substr($0, rindex($0, '/') + 1), 0, index(substr($0, rindex($0, '/') + 1), '.pl')); } my $writeMessage = sub { my ($self, $message, $level, @params) = @_; if (defined $self->{level}){ if ($level < $self->{level}) { return; } }else{ if ($level < 0) { return; } } my $handle = $self->{handle}; printf($handle $layout, &getTS(), $levels{$level}, $message); }; sub trace { my ($self, $message, @params) = @_; $self->$writeMessage($message, 0, @params); } sub debug { my ($self, $message, @params) = @_; $self->$writeMessage($message, 1, @params); } sub info { my ($self, $message, @params) = @_; $self->$writeMessage($message, 2, @params); } sub warn { my ($self, $message, @params) = @_; $self->$writeMessage($message, 3, @params); } sub error { my ($self, $message, @params) = @_; $self->$writeMessage($message, 4, @params); } sub fatal { my ($self, $message, @params) = @_; $self->$writeMessage($message, 5, @params); } sub isTrace { my ($self) = @_; return $self->{level} == 0; } sub isDebug { my ($self) = @_; return $self->{level} <= 1; } sub isInfo { my ($self) = @_; return $self->{level} <= 2; } sub isWarn { my ($self) = @_; return $self->{level} <= 3; } sub isError { my ($self) = @_; return $self->{level} <= 4; } sub isFatal { my ($self) = @_; return $self->{level} <= 5; } sub initialize { my ($self, $l_file, $level) = @_; eval { open($self->{handle}, $append, $l_file) || die $!; }; if ($@) { printf("Error opening log file [%s] - %s", $l_file, $@); return 0; } my %rlevels = reverse(%levels); my $key = $rlevels{$level}; $self->{level} = $key; return 1; } sub getCLMServerPID{ $rc = 0; if (-e $CFG{'PID_FILE_FULL_PATH'}){ open PIDFILE, "<$CFG{'PID_FILE_FULL_PATH'}" or die "Unable to open server pid file.\n"; while(){ $clmServerPID = $_; $clmServerPID =~ s/\s+\z//; } close(PIDFILE); $rc = 1; }else{ $logWriter->info("[FILE NOT FOUND]: WAS pid file was not found at $CFG{'PID_FILE_FULL_PATH'}"); $rc = 0; } return $rc } sub stopCLMServer{ $rc = 0; $clmServerCMD=($^O=~/Win/)?("$CFG{'SERVER_BIN_PATH'}stopServer.bat $CFG{'CLM_SERVER_PROFILE_NAME'}"):("$CFG{'SERVER_BIN_PATH'}stopServer.sh $CFG{'CLM_SERVER_PROFILE_NAME'}"); my $pidCheck = getCLMServerPID; if ($pidCheck eq 1){ #pid found $logWriter->info("PID File Found. Executing $clmServerCMD."); print "Executing $clmServerCMD\n"; my $clmServerResponse = qx($clmServerCMD); if(-e "$CFG{'PID_FILE_FULL_PATH'}"){ #pid file exists force quit WAS... #log response above as error $logWriter->error("[STOP SERVER RESPONSE]: \n$clmServerResponse"); $rc = 0; }else{ #pid file was removed proceed to restart WAS #log response above as success $logWriter->info("[STOP SERVER RESPONSE]: \n$clmServerResponse"); $rc = 1; } }else{ #no pid found WAS assumed not running so start WAS $logWriter->info("PID File NOT Found. Skipping the Stop Server Command."); $rc = 1; } return $rc; } sub forcefulProcessTermination{ #This method is only used when a graceful clm server stop cannot be achieved. $rc = 0; if (getCLMServerPID eq 1){ #TODO: find the running process using the server pid $rc = 1; } return $rc; } sub startCLMServer{ $rc = 0; $clmServerCMD=($^O=~/Win/)?("$CFG{'SERVER_BIN_PATH'}startServer.bat $CFG{'CLM_SERVER_PROFILE_NAME'}"):("$CFG{'SERVER_BIN_PATH'}startServer.sh $CFG{'CLM_SERVER_PROFILE_NAME'}"); $logWriter->info("Executing $clmServerCMD"); print "Executing $clmServerCMD\n"; my $clmServerResponse = qx($clmServerCMD); if(-e "$CFG{'PID_FILE_FULL_PATH'}"){ #pid file exists indicating WAS started #log response above as success $logWriter->info("[START SERVER RESPONSE]: \n$clmServerResponse"); $rc = 1; }else{ #pid file not created indicating WAS never started #log response above as error $logWriter->error("[START SERVER RESPONSE]: \n$clmServerResponse"); $rc = 0; } return $rc; } sub doCURL{ if("$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_JTS'}" ne "NA"){ $jtsCurlCmd=($^O=~/Win/)?($dir."curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_JTS'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}\" -o /dev/null"):("curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_JTS'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}\" -o /dev/null"); }else{ $jtsCurlCmd = "NA"; } if("$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RQM'}" ne "NA"){ $qmCurlCmd=($^O=~/Win/)?($dir."curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RQM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}\" -o /dev/null"):("curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RQM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}\" -o /dev/null"); }else{ $qmCurlCmd = "NA"; } if("$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_CCM'}" ne "NA"){ $ccmCurlCmd=($^O=~/Win/)?($dir."curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_CCM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}\" -o /dev/null"):("curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_CCM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}\" -o /dev/null"); }else{ $ccmCurlCmd = "NA"; } if("$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'}" ne "NA"){ $rmCurlCmd=($^O=~/Win/)?($dir."curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'}\" -o /dev/null"):("curl -ks -w \"%{http_code}\" \"$CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'}\" -o /dev/null"); }else{ $rmCurlCmd = "NA"; } #CHECK JTS SERVER RESPONSE if($jtsCurlCmd ne "NA"){ $logWriter->info("Checking server response from jts/admin..."); print "Checking server response from jts/admin..."; my $response = qx($jtsCurlCmd); if($response eq 200){ $logWriter->info("[JTS_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_JTS'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}: $response"); }else{ $logWriter->error("[JTS_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_JTS'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}: $response"); $stopRestartFlag = 1; } $jtsResponseCheckFlag = 1; print "$response\n"; }else{ $logWriter->info("[JTS_SKIPPED]: JTS Response Not checked as no context root is specified in the properties file"); print "Skipping JTS Server Response check as there was no JTS context specified in the properties file...\n"; $jtsResponseCheckFlag = 0; } #CHECK RQM SERVER RESPONSE if($qmCurlCmd ne "NA"){ $logWriter->info("Checking server response from qm/admin..."); print "Checking server response from qm/admin... "; my $response = qx($qmCurlCmd); if($response eq 200){ $logWriter->info("[QM_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RQM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}: $response"); }else{ $logWriter->error("[QM_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RQM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}: $response"); $stopRestartFlag = 1; } $qmResponseCheckFlag = 1; print "$response\n"; }else{ $logWriter->info("[QM_SKIPPED]: QM Response Not checked as no context root is specified in the properties file"); print "Skipping QM Server Response check as there was no QM context specified in the properties file...\n"; $qmResponseCheckFlag = 0; } #CHECK CCM SERVER RESPONSE if($ccmCurlCmd ne "NA"){ $logWriter->info("Checking server response from ccm/admin..."); print "Checking server response from ccm/admin..."; my $response = qx($ccmCurlCmd); if($response eq 200){ $logWriter->info("[CCM_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_CCM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}: $response"); }else{ $logWriter->error("[CCM_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_CCM'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_ADMIN'}: $response"); $stopRestartFlag = 1; } $ccmResponseCheckFlag = 1; print "$response\n"; }else{ $logWriter->info("[CCM_SKIPPED]: CCM Not checked as no context root is specified in the properties file"); print "Skipping CCM Server Response check as there was no CCM context specified in the properties file...\n"; $ccmResponseCheckFlag = 0; } #CHECK RM SERVER RESPONSE if($rmCurlCmd ne "NA"){ $logWriter->info("Checking server response from rm/web..."); print "Checking server response from rm/web..."; my $response = qx($rmCurlCmd); if($response eq 200){ $logWriter->info("[RM_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'}: $response"); }else{ $logWriter->error("[RM_RESPONSE]: $CFG{'PUBLIC_URI_HOSTNAME'}$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'}: $response"); $stopRestartFlag = 1; } $rmResponseCheckFlag = 1; print "$response\n"; }else{ $logWriter->info("[RM_SKIPPED]: RM Not checked as no context root is specified in the properties file"); print "Skipping RM Server Response check as there was no RM context specified in the properties file...\n"; $rmResponseCheckFlag = 0; } if($stopRestartFlag eq 1){ #Attempt WAS Restart Procedure my $stopResponse = stopCLMServer; if ($stopResponse eq 1){ #Restart WAS $logWriter->info("WAS successfully stopped. Attempting restart..."); print "WAS successfully stopped. Attempting restart...\n"; my $startResponse = startCLMServer; if ($startResponse eq 1){ #all good $logWriter->info("WAS successfully restarted."); print "WAS successfully restarted.\n"; }else{ #unable to start WAS $logWriter->error("Unable to start WAS."); print "Unable to start WAS.\n"; } }else{ $logWriter->error("Unable to stop WAS."); print "Unable to stop WAS.\n"; } }else{ $curlCompletionMsg = "All server response checks ("; if ($jtsResponseCheckFlag eq 1){ $curlCompletionMsg = $curlCompletionMsg." jts"; } if ($qmResponseCheckFlag eq 1){ $curlCompletionMsg = $curlCompletionMsg." qm"; } if ($ccmResponseCheckFlag eq 1){ $curlCompletionMsg = $curlCompletionMsg." ccm"; } if ($rmResponseCheckFlag eq 1){ $curlCompletionMsg = $curlCompletionMsg." rm"; } $curlCompletionMsg = $curlCompletionMsg." ) completed with response 200."; $logWriter->info("$curlCompletionMsg"); print "$curlCompletionMsg\n"; } } sub readPropertiesFile(){ $logWriter->info("Reading properties file."); print "Reading properties file.\n"; open CFGFILE, "<$propsFile" or die "Unable to open properties file.\n"; while(){ my $propsLine= $_; my @vals = split('=',$propsLine); $cfgKey = $vals[0]; $cfgValue = $vals[1]; $cfgValue =~ s/\s+\z//; $cfgKey =~ s/\s+\z//; if($cfgValue eq ""){ $cfgValue = "NA"; } if($cfgKey=~/CONTEXT/){ $CFG{'CONTEXT_ROOTS'}{$cfgKey}= $cfgValue || die("Unknown Property: $cfgKey \n"); }else{ $CFG{$cfgKey} = $cfgValue || die("Unknown Property: $cfgKey \n"); if($cfgKey=~/WAS_SERVER_PROFILE_PATH/){ #Add CFG Values for Server PID File #Get Array of server path elements @pidFileElements = split($backSlashChar,$CFG{'WAS_SERVER_PROFILE_PATH'}); #check to see if we are using forward slash notation or backslash notation with the server path #If the following check is 0 it means that no backslashes were found in the path so implied unix style. if($#pidFileElements eq 0){ @pidFileElements = split($forwardSlashChar,$CFG{'WAS_SERVER_PROFILE_PATH'}); #folder name where the pid file can be found. $pidFileFolder = $CFG{'WAS_SERVICE_NAME'}; #pid file name (ex: server1.pid) $pidFileName = $pidFileFolder.".pid"; #for each element (directory) of the WAS_SERVER_PROFILE_PATH, Build the path to get us to the pid file foreach (@pidFileElements){ if($pidFileFullPath eq ""){ if($_ ne ""){ $pidFileFullPath = "/".$_; } }else{ $pidFileFullPath = $pidFileFullPath."/".$_; } } #create a variable with a path to the properties folder (where the soap creds file lives) $scfPath = $pidFileFullPath."/properties"; #create a variable with a path to the bin folder (where stop/Start Server commands live) $sbPath = $pidFileFullPath."/bin/"; #create a variable with the full path to the folder where the pid file lives $pidFileDirPath = "$CFG{'WAS_SERVER_PROFILE_PATH'}logs/$CFG{'WAS_SERVICE_NAME'}"; $clmServerProfileName = $pidFileFolder; #create a variable with the complete path to the pid file $pidFileFullPath = "$CFG{'WAS_SERVER_PROFILE_PATH'}logs/$CFG{'WAS_SERVICE_NAME'}/".$pidFileName; }else{ #If we are here it means that backslashes were found in the path so implied windows style. #folder name where the pid file can be found. $pidFileFolder = $CFG{'WAS_SERVICE_NAME'}; #pid file name (ex: server1.pid) $pidFileName = $pidFileFolder.".pid"; #for each element (directory) of the WAS_SERVER_PROFILE_PATH, Build the path to get us to the pid file foreach (@pidFileElements){ if($pidFileFullPath eq ""){ $pidFileFullPath = $_; }else{ $pidFileFullPath = $pidFileFullPath."\\".$_; } } #create a variable with a path to the properties folder (where the soap creds file lives) $scfPath = $pidFileFullPath."\\properties"; #create a variable with a path to the bin folder (where stop/Start Server commands live) $sbPath = $pidFileFullPath."\\bin\\"; $clmServerProfileName = $pidFileFolder; #create a variable with the full path to the folder where the pid file lives $pidFileDirPath = $pidFileFullPath."\\logs\\server1\\"; #create a variable with the complete path to the pid file $pidFileFullPath = $pidFileFullPath."\\logs\\server1\\".$pidFileName; } #end else for if($#pidFileElements eq 0) #Update Config Hash with derived values $CFG{'PID_FILE_NAME'} = $pidFileName; $CFG{'PID_FILE_FULL_PATH'} = $pidFileFullPath; $CFG{'PID_FILE_DIR_PATH'} = $pidFileDirPath; $CFG{'SERVER_BIN_PATH'} = $sbPath; $CFG{'SERVER_CREDS_FILE_PATH'} = $scfPath; $CFG{'CLM_SERVER_PROFILE_NAME'} = $clmServerProfileName; } #end if($cfgKey=~/WAS_SERVER_PATH/) } #end else for if($cfgKey=~/CONTEXT/) $logWriter->info("[Property:Value] $cfgKey: $cfgValue"); } $logWriter->info("Closing properties file."); print "Closing properties file.\n"; close(CFGFILE); #make sure RM context set to /web if($CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'}=~/web/){ #currently set to rm/web appropriately }else{ $CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'} = "$CFG{'CONTEXT_ROOTS'}{'CONTEXT_ROOT_RM'}/web"; } } sub main{ $logWriter->info("Starting checkCLM script."); print "Starting checkCLM script.\n"; readPropertiesFile; $logWriter->info("Beginning Server Response Checks:"); print "Beginning Server Response Checks:\n"; doCURL; $logWriter->info("Cleaning up and closing log file."); print "Cleaning up and closing log file.\n"; $logWriter->info("Stopping checkCLM script."); print "Stopping checkCLM script.\n"; $logWriter->DESTROY(); } main();