package Health::VE;
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>

#  $Name: bld21_017 $ 
#  $Id: VE.pm,v 1.3 2005/04/20 17:23:35 sbrooks Exp $


use base 'Health';
use NWS::VE;
use Ilist;
use Message;
use Report;
use Catalog;
use Events;
use strict;
use Debug;

sub revision {'$Revision: 1.3 $'}


sub all_logic {
  my($hm, $report) = @_;
  my($ev, $ed, $pertains, $x ,$y, $contain, $sd);
  my($orep, $key);
  my($rep)     = $report->content;
  my($oreport) = PDM->getOldReport($report->fileKey);
  my($ip)      = $report->id('ip');
  my($name)    = $report->name;
  my $wwn      = $report->id('deviceName');
  my($id)      = $report->id('display');
  my $mgmtLevel = $report->value('id.mgmtLevel') || 'D';
  my($log)     = $report->log();
  if (!$wwn) {
    Debug->errNoRepeat(T3_NO_KEY => $ip, 24, "VE ($name/$ip) cannot be identified");
     return;
  }
  CIM->version("1.1");
  $DB::single = 1;

  return if ($hm->connectionEvent($wwn, $report, {method => 2, threshold_severity => 0} ));

  my $freq  = System->get_renv()->{audit_freq} || 7;
  my $audit = System->get_audit() ? "YES" : Timer->isXdays("Audit$wwn", $freq);

  if (!$oreport || $audit eq "YES" ) {  # new t300 or audit time.
     my($etype) = $audit eq "YES" ? "ve.AuditEvent" : "ve.DiscoveryEvent";
     my($title) = $audit eq "YES" ? "Auditing a":"Discovered a new";
     my($dt)    = "A" if (!$audit);
     Grid->setCode($etype);
     $ev = CIM::Instance->new('NWS_Event', [
                  [ EventType   => $etype ],
                  [ EventId     => PDM->getEventSequence  ],
                  [ MgmtLevel   => $mgmtLevel],
                  [ Target      => "ve:$wwn" ], 
                  [ TargetName  => $id  ], 
                  [ Description => "$title Virtualization Engine called $id"],
                  [ Data        => $hm->serial($rep) ],
                         ]);

     $sd = Events->sourceDetector({ event => $ev , host => 1, rep => $rep});
      
     my($p) = NWS::VE->newSystem($rep);

     $pertains = CIM::Instance->new('NWS_EventPertainsToSystem', [
                  [ Event       => $ev  ],
                  [ Element     => $p->[0] ],
                  [ DiscoveryType => $dt],
                    ]);

     my($monitors) = CIM::Instance->new('NWS_AgentMonitors', [
                  [ Agent       => $sd->[0]  ],
                  [ Element     => $p->[0] ],
                    ]);

     $ed = Message->new( { id        => $report->id,
                            instances => [$ev, @$sd,  @$p, $monitors, $pertains ],
                            severity  => Message::SEVERITY_NORMAL });

     PDM->saveMessage($ed);
  }
  $orep = $oreport->content() if ($oreport);

  return if (!$oreport);

  $hm->locationChangeEvent($report, $rep, $orep, $wwn);

  # FC-EVENTS
  $hm->fcEvent($rep->{FC_COUNTERS}, $orep->{FC_COUNTERS});

#  generate events for the important counters 
#
if (0) {
  my($port);
  my($data);
  foreach $x ('host','device') {
     $port = "fc.$x"; 
     my($rep1) = $rep->subset("fc.$x");
     foreach my $val (keys %$rep1) {
         my($old) = $orep->get("fc.$x.$val");
         my($new) = $rep->get("fc.$x.$val");
         if ($new > $old) {
           my($level, $cnt, $desc, $mins) = 
               Thresholds->test('ve',$val, $x, $new-$old);
           my($tx)  = "Port-$x: Received $cnt '$desc' in $mins mins (value=$new)";

           if ($level eq "W" || $level eq "E") {
             $data .= "$tx\n";
           }
         }
     }
  }
  if ($data) {
      chop($data);
      Grid->setCode("ve.LogEvent.statistics");
      $hm->logEvent($data, $report,  $wwn, "Change in Port Statistics on VE $id:",  Message::SEVERITY_WARNING );
  }
}

  $hm->identificationEvent($report, $orep->{'initiator.wwn'}, $rep->{'initiator.wwn'}, $wwn);

# 
#  add events for changes in the status of the volumes generated
#  by the vicom.
#
  my $log = $rep->subset('logical');
  my $olog = $orep->subset('logical');
  my $first;
  foreach my $k (keys %$log) {
     if ($k =~ /(T\d+).map.Type/) {
        my $vol = $1;
        my $serial = $log->{"$vol.map.Drive_Serial#"};

        my $active = $log->{"$vol.map.Active_Path"};
        my $active_wwn = $rep->{"target.$active.uid"};
        my $passive = $log->{"$vol.map.Passive_Path"};
        my $passive_wwn = $rep->{"target.$passive.uid"};
        my $info = "$serial(active=$active_wwn,passive=$passive_wwn)";

        my $owwn = $olog->{"$vol.map.Drive_Serial#"} || '[Undefined]';
        my $oactive = $olog->{"$vol.map.Active_Path"};
        my $oactive_wwn = $orep->{"target.$active.uid"};
        my $opassive = $olog->{"$vol.map.Passive_Path"};
        my $opassive_wwn = $orep->{"target.$passive.uid"};
        my $oinfo = "$owwn(active=$oactive_wwn,passive=$opassive_wwn)";
        chop($info) if (System->get_bad_health() && $first++ == 0);
        if ($info ne $oinfo) {
          my($desc) = "LogicalID $vol on VE $id changed from $oinfo to $info";
          my $sev = (length($info) < length($oinfo)) ? Message::SEVERITY_WARNING : Message::SEVERITY_NORMAL;
          Grid->setCode("ve.AlarmEvent.volume");
          my $ev = $hm->valueChangeEvent($vol, "", $report, $wwn, $desc, 1, "volume" , {noState => 1 });
          State->saveState("ve", $wwn, "multipath.status", $name,
                           Message::SEVERITY_WARNING, $desc, 1, $ev);
        }
     }
  }
  $first = 0;
  foreach my $k (keys %$olog) {
       if ($k =~ /(T\d+).serial/) {
         if (!$log->{$k} || ( System->get_bad_health() && $first++ == 0) ) {
            my $vol = $1;
            my $val  = $olog->{$k};
            my($desc) = "VLUN $vol/$val on VE $id is not present";
            Grid->setCode("ve.AlarmEvent.volume_delete");
            my $ev = $hm->valueChangeEvent($vol, "", $report, $wwn, $desc, 0, "volume_delete", {noState => 1});
            State->saveState("ve", $wwn, "vlun.status", $name, 
                           Message::SEVERITY_ERROR, $desc, 0 , $ev );
         }
       }
  }
  foreach my $k (keys %$log) {
       if ($k =~ /(T\d+).serial/) {
         if (!$olog->{$k}) {
            my $vol = $1;
            my $val  = $log->{$k};
            my($desc) = "VLUN $vol/$val on $id was added";
            Grid->setCode("ve.AlarmEvent.volume_add");
            $hm->valueChangeEvent($vol, "", $report, $wwn, $desc, 0, "volume_add" );
         }
       }
  }
}

  
1;

