#  $Header: emrepnotif.pl 18-may-2007.10:02:05 tsubrama Exp $
#
# Copyright (c) 2001, 2007, Oracle. All rights reserved.  
#
#    NAME
#      emrepnotif.pl 
#
#    DESCRIPTION
#      It connects to a database, executes a user-defined SQL
#
#    NOTES
#
#    MODIFIED   (MM/DD/YY)
#      tsubrama 05/17/07 - removing double quotes in the subject and msg
#      aholser  01/24/05 - improve reliability
#      aholser  09/10/04 - linux port
#      kranjan  07/19/04 - Fix for Bug 3734381
#      aholser  10/21/03 - remove tracing pwd 
#      aholser  10/18/03 - 
#      aholser  08/04/03 - notif delivery job gone 
#      aholser  04/29/03 - minor changes
#      aholser  04/15/03 - aholser_aa
#      aholser  04/15/03 - 
#      aholser  12/31/02 - Creation
#

use strict;
use Oraperl;
use Time::HiRes;

require "emd_common.pl";
require "semd_common.pl";

my $targetname = "";
my $db_connect = "";
my $emConsoleMode = "";
my $propertiesFile = "$ENV{EMDROOT}/sysman/config/emoms.properties";
my $consoleModeProperty = "oracle.sysman.emSDK.svlt.ConsoleMode";
my $jobLike = "EMD_NOTIFICATION.%";
my %omsProps;
if (-e $propertiesFile)
{
  %omsProps = &parseFile($propertiesFile);
  if (defined($omsProps{$consoleModeProperty}))
  {
    my $propValue = $omsProps{$consoleModeProperty};
    if ($propValue eq "dbStandalone")
    {
      $emConsoleMode = "STANDALONE";
    }
    if ($propValue eq "standalone")
    {
      $emConsoleMode = "DBCONSOLE";
    }
  }
  else
  {
    $emConsoleMode = "CENTRAL";
  }
}
else
{
  $emConsoleMode = "STANDALONE";
}

if($emConsoleMode ne "CENTRAL")
{
  $jobLike = "EMD_MAINTENANCE%";
}
 
EMD_PERL_DEBUG("emrepnotif: Connectdescriptor $ENV{CONNECTDESCRIPTOR}");
EMD_PERL_DEBUG("emrepnotif: emConsoleMode=$emConsoleMode jobLike=$jobLike");
if ( $ENV{CONNECTDESCRIPTOR} ne "" )
{
  $db_connect = $ENV{EM_REPOS_USER} . "/" . $ENV{EM_REPOS_PWD} . "@" . $ENV{CONNECTDESCRIPTOR};
  $targetname = $ENV{EM_REPOS_USER}."test";
}
else
{
  $db_connect = $ENV{EM_REPOS_USER} . "/" . $ENV{EM_REPOS_PWD} . "@" . $ENV{EM_TARGET_ADDRESS};
  $targetname = $ENV{SID}.$ENV{PORT};
}

my $start_time = Time::HiRes::time;

my $lda;

my $targetname = $ENV{SID}.$ENV{PORT};
my $fn = get_tmp_filename ($targetname, "emrepnotif");
EMD_PERL_DEBUG("emrepnotif: $targetname, $fn");

# If we can't connect we'll exit.  The error will be caught by emrepresp.pl
unless ( $lda = &ora_login ('', $db_connect, '') )
{ 
   EMD_PERL_ERROR("emrepnotif: ora_login error: $ora_errstr - exiting");
   exit 0; 
}

register_metric_call($lda);

my $sql = "SELECT 
           (SELECT count(broken) FROM user_jobs 
              WHERE what LIKE('$jobLike')
              AND broken = 'Y'),
           (SELECT MIN(SYSDATE-next_date) FROM user_jobs
              WHERE what LIKE('$jobLike')),
           NVL((SELECT AVG(value) FROM mgmt_system_performance_log 
              WHERE job_name like('$jobLike')
              AND name='Queued Notifications'
              AND time>(SYSDATE-(1/24))),0),
           (SELECT DECODE(COUNT(a.device_name), 0, -1, COUNT(a.device_name)) - COUNT(b.device_name)
              FROM mgmt_notify_devices a, mgmt_notify_devices b
              WHERE b.status = 0) FROM DUAL";

EMD_PERL_DEBUG("emrepnotif: sql is: $sql");
my $cur;

unless ($cur = &ora_open ($lda, $sql))
{ 
   EMD_PERL_ERROR("emrepnotif: ora_open error: $ora_errstr - exiting");
   exit 1; 
}

my @fetch_row;
my $jobUpDown;
my $schedule;
my $waiting;
my $devicesup;

unless (@fetch_row = &ora_fetch($cur))
{ 
   EMD_PERL_ERROR("emrepnotif: ora_fetch error: $ora_errstr - exiting");
   exit 1; 
}

$jobUpDown = $fetch_row[0];
$schedule = $fetch_row[1];
$waiting = $fetch_row[2];
$devicesup = $fetch_row[3];

EMD_PERL_DEBUG("emrepnotif: query result is:\nem_result=$jobUpDown|$waiting|$devicesup\n");

if($jobUpDown > 0) 
{
   print ("em_result=DOWN|SEVERE NOTIFICATION DBMS JOB ERROR: Notification dbms job is down");
   EMD_PERL_ERROR("SEVERE NOTIFICATION DBMS JOB ERROR: Notification dbms job is down");
   processfailure("SEVERE NOTIFICATION DBMS JOB ERROR: Notification dbms job is down");
}
else
{ if($waiting > 500)
  {
    print ("em_result=DOWN|SEVERE NOTIFICATION BACKLOG: $waiting Notifications are waiting to be delivered");
    EMD_PERL_ERROR("SEVERE NOTIFICATION BACKLOG: $waiting Notifications are waiting to be delivered");
    processfailure("SEVERE NOTIFICATION BACKLOG: $waiting Notifications are waiting to be delivered");
  }
  else
  { if($devicesup = 0)
    {
      print ("em_result=DOWN|NOTIFICATION DELIVERY NOT POSSIBLE: All notification methods are down");
      EMD_PERL_ERROR("NOTIFICATION DELIVERY NOT POSSIBLE: All notification methods are down");
      processfailure("NOTIFICATION DELIVERY NOT POSSIBLE: All notification methods are down");
    }
    else
    # If the next schedule time is more than 2 hours in the past or a year in the future, the 
    # schedule is invalid and the job is broken.
    { if(($schedule > 1/12) || ($schedule < -365))
      {
         print ("em_result=DOWN|NOTIFICATION JOB ERROR: Job schedule time is invalid");
         EMD_PERL_ERROR("NOTIFICATION JOB ERROR: Job schedule time is invalid");
         processfailure("NOTIFICATION JOB ERROR: Job schedule time is invalid");
      }
      else
      {
         print ("em_result=UP|Notification System is working properly");
      }
    }
  }
}

&ora_logoff($lda) || warn "ora_logoff($lda): $ora_errno: $ora_errstr\n";

my $end_time = Time::HiRes::time;
my $logon_time = ($end_time - $start_time) * 1000;
EMD_PERL_DEBUG("emrepnotif: Time in emrepnotif: $logon_time" );

exit 0;

sub processfailure
{
   my $mailscript = "emrepdown.pl";
   my $exists = -e $fn;
   my $mailscriptexists = -e $mailscript;
   my $accesstime = -M $fn;
   my $interval = 1/24;
   my $home = $ENV{ORACLE_HOME};
   EMD_PERL_DEBUG("emrepnotif: exists=$exists, accesstime=$accesstime, interval=$interval mailscriptexists=$mailscriptexists" );
    
   # Email is sent if the error is new ($fn doesn't exist) or more than one hour has elapsed.
   if(($exists < 1) || ($accesstime > $interval))
   {
      EMD_PERL_DEBUG("emrepnotif: sending email" );
      if($exists > 0)
      {
         unlink($fn);
      }
     
      open(FILE, ">".$fn);
      print FILE scalar localtime;
      close(FILE);
      if($mailscriptexists < 1)
      {
         if( $home ne "" )
         {
            $mailscript =  "$home/bin/emrepdown.pl";
            $mailscriptexists = -e $mailscript;
            if($mailscriptexists < 1)
            {
               $mailscript =  "$home/emagent/sysman/admin/scripts/emrepdown.pl";
               $mailscriptexists = -e $mailscript;
               if($mailscriptexists < 1)
               {
                  EMD_PERL_DEBUG("emrepnotif: Can't locate emrepdown.pl script: ORACLE_HOME=$home - exiting");
                  return;
               }
            }
         }
      }

      {
         local @ARGV;

         my ($message) = @_;
         
         $ARGV[0] = $message;
         $ARGV[1] = "Severe Enterprise Manager Notification subsystem problem";

         EMD_PERL_ERROR("emrepnotif: processfailure $mailscript, Message:$ARGV[0], Subject:$ARGV[1]");

         #since ARGV is local variable,it's values are directly accessible in the mailscript.
         #The do() method executes the contents of the file as a Perl script.
         do($mailscript);
      }
      close(FH);
      return;
  }
  EMD_PERL_DEBUG("emrepnotif: processfailure $fn already exists and less than one hour since last email");
}

sub parseFile
{
  my($fname) = @_;
  my %lprop;

  if (! -T $fname ) {
     print "File $fname is not a text file\n";
     next;
  }
  open(FILE,$fname) or die "Can not read file: $fname\n$!\n";
  while (<FILE>) 
  {
    ;# Remove leading and traling whitespaces
    s/^\s+|\s+$//;
    s/#.*$//g;

    ;# Validate each non-empty line
    if (! /^$/) 
    {
       my($name,$value) = /([^=]+)\s*=\s*(.+)/;
       if (defined($name) && defined($value))
       {
          $name  =~ s/^\s+|\s+$//g;
          $value =~ s/^\s+|\s+$//g;
          $lprop{$name} = $value;
       }
    }
  }
  close(FILE);

  ;# Return success
  return %lprop;
}



