#!/usr/local/bin/perl
# 
# $Header: emdb/sysman/admin/scripts/rac/cls_services.pl /st_emdbsa_11.2/13 2010/01/04 10:35:47 sksantha Exp $
#
# cls_services.pl
# 
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 
#
#    NAME
#      cls_services.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#      <short description of component this file declares/defines>
#	Use srvctl commands to retrieve information about Cluster Managed Services for rac_databases 
#	for a given cluster, use srvctl config to get list of rac database names
#	for each rac database use srvctl status service -d dbname -S 1 -f  to get list of services
# 	for each service following information is collected
#	service_name, enabled/disabled, tafpolicy, preferred instance list, available instance list,
#	running instance list
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
#    MODIFIED   (MM/DD/YY)
#    pardutta    11/04/09 - RAC One Node: collect and update Database Type.
#    pardutta    06/09/09 - Total active server count.
#    pardutta    05/21/09 - Exclude internal service from services list.
#    pardutta    03/31/09 - Changes to update database service record in
#                           mgmt_rac_services.
#    rsamaved    12/31/08 - run srvctl service commands from db home
#    gallison    12/01/08 - Fix for in-view services
#    rsamaved    08/13/08 - 
#    sadattaw    03/05/08 - adding support for monitoring 11.2 cluster targets
#    sadattaw    03/01/07 - XbranchMerge rsamaved_demosa from st_emdbsa_11.1
#    rsamaved    01/31/07 - use em_error for err cases
#    kramarat    01/25/07 - XbranchMerge kramarat_cluster_db_services_fix2 from
#                           main
#    sadattaw    09/28/06 - collect cluster managed services information
#    sadattaw    09/28/06 - Creation
# 

use strict;
use DBI qw(:sql_types);
use Cwd;

require "$ENV{EMDROOT}/sysman/admin/scripts/db/dbstate.pl";

BEGIN
{
 # temporarly setting environment only in dev view env
 # this code is not active in production
 if ( $ENV{ADE_VIEW_ROOT} and not $ENV{HAS_USE_SHIPHOME} )
 {
  my $advrt =  $ENV{ADE_VIEW_ROOT};
  $advrt  =~ s/_ag$//;
  $advrt  = $advrt."t";

  $ENV{ORA_CRS_HOME}="$advrt/oracle";
  $ENV{CSS_CLUSTERNAME}='newdb_cluster';

  $ENV{EM_CRS_HOME}="$ENV{ORA_CRS_HOME}";
  $ENV{CRS_HOME}="$ENV{ORA_CRS_HOME}";
  $ENV{CV_HOME}="$ENV{CRS_HOME}";
  $ENV{OCR_ROOT}="$ENV{CRS_HOME}/has_work/ocr.dat";
  $ENV{OCR_LOC}="$ENV{CRS_HOME}/has_work/ocr.loc";
  $ENV{CV_JDKHOME}="$ENV{CRS_HOME}/jdk15";
  $ENV{OCR_DEVELOPER_ENV}='TRUE';
  $ENV{ORA_ENVIRON_OPTS}='true';
  $ENV{ORA_CSS_VARS}='true';

  my $libs = "$ENV{CRS_HOME}/lib:$ENV{CRS_HOME}/has/lib:$ENV{CRS_HOME}/opsm/lib";
  $ENV{LD_LIBRARY_PATH}="$libs:$ENV{LD_LIBRARY_PATH}" if $ENV{LD_LIBRARY_PATH};
  $ENV{LD_LIBRARY_PATH}="$libs" unless $ENV{LD_LIBRARY_PATH};
  $ENV{PATH}="$ENV{CRS_HOME}/bin:$ENV{CRS_HOME}/has/bin:$ENV{PATH}" if $ENV{PATH};
  $ENV{PATH}="$ENV{CRS_HOME}/bin:$ENV{CRS_HOME}/has/bin" unless $ENV{PATH};

my $clusternm = "newdb_cluster";
 }
}

my $crsHome = $ENV{EM_CRS_HOME};
EMD_PERL_DEBUG( "EM_CRS_HOME returned $crsHome \n");

$crsHome = $ENV{CRS_HOME} if ($crsHome eq "");
print( "CRS_HOME returned $crsHome \n");

#comment following for testing in view
my %stdinArgs = get_stdinvars();
my $clusternm = $stdinArgs{"EM_TARGET_CLUSTER_NAME"};

my %sg_maxsize = {};
my $clusterSize = 1;

EMD_PERL_DEBUG( "EM_TARGET_CLUSTER_NAME = $clusternm \n");

if ($crsHome eq "" || $crsHome eq "#CRS_HOME#" || $clusternm eq "")
{
    EMD_PERL_DEBUG("Ignoring cluster Services metric: either no CRS_HOME or cluster name is not found \n");
}   
else
{

    $clusterSize = get_cluster_size();
print " ClusterSize = $clusterSize \n ";

#call get_dbnames to retrieve Rac Database names on this cluster, using srvctl config\n";
    my @dblist = get_dbnames();
#    print " get_dbnames returned : \n";


    my $srv_types = {};
    my $availlist = {};
    my $preflist = {};
    my @runlist = ();
    my $tafpolicy = {};
    my $enabled = {};
    my $srvgrp = {};
    my $resnames = {};
    my $srv_cardinality = {};
    my $db = '';
    my @all_services;		
    my %srvpool_cardinality_info = ();
    foreach $db (@dblist)
    {
        my @dbprops = split(',', $db);
        my $dbnm = shift(@dbprops);
        my $dbhom = shift(@dbprops);
	my $dbtype = shift(@dbprops);
        EMD_PERL_DEBUG( "db name: $dbnm  db home: $dbhom db type: $dbtype\n");
	my @kys = keys(%srvpool_cardinality_info);
	if(@kys == 0)
	{
	    %srvpool_cardinality_info = get_srvpool_cardinality($dbhom);
	}

	push(@all_services, add_database_service_record($dbnm, $dbhom, $clusternm, $dbtype));

	my @service_names = ();

#	print "calling get_service_status to retrieve service names using srvctl \n";
	my $res = '';
	$res = get_service_config($dbnm, $dbhom);
	if (! defined $res)
        {
            print "em_error=get_service_config returned null, possible errs found \n";
            EMD_PERL_DEBUG( "em_error=get_service_config returned null, possible errs found\n");
	    next;
        }
        else
        {
#	    print " get_service_config returned : $res \n";
	    EMD_PERL_DEBUG( "get_service_config returned $res \n");

	    # clear arrays before getting info for this db
    ##splice(@service_names, 0);
	    $srv_types = {};
	    $availlist = {};
	    $preflist = {};
	    $tafpolicy = {};
	    $enabled = {};
	    $srvgrp = {};
	    $srv_cardinality = {};
    	    $resnames = {};

	    @service_names = parse_serviceconfig_res($res, \$srv_types, \$availlist, \$preflist, \$tafpolicy, \$enabled, \$srvgrp, \$resnames, \$srv_cardinality);
        } # else

	$res = '';
	$res = get_service_status($dbnm, $dbhom);
	if (!defined $res)
        {
            print "em_error=get_service_status returned null, possible errs found \n";
            EMD_PERL_DEBUG( "em_error=get_service_status returned null, possible errs found\n");
	    next;
        }
        else
        {
	    print " get_service_status returned : $res \n";
	    EMD_PERL_DEBUG( "get_service_status returned $res \n");
	 
	    # clear arrays before getting info for this db
    ##splice(@service_names, 0);

	    splice(@runlist, 0);

	    parse_servicestat_res($res, \@runlist);

        } # else


#    	print "Service names from srvctl \n";
	    EMD_PERL_DEBUG( "Service names from srvctl \n");

	    my $i = 0;
	    my $nm = '';
	    foreach $nm (@service_names)
	    {
## print " service name : $nm ";
	    # get cardinality value for service
	    my $cardnl = 0;
	    if (lc($srv_cardinality->{$nm}) eq "singleton")
	    {
		$cardnl = 1;
	    } elsif(lc($srv_cardinality->{$nm}) eq "uniform")
	    {
    		$cardnl = $srvpool_cardinality_info{"ora.".$srvgrp->{$nm}}; 
	    }
	    else 
	    {
		$cardnl = 0;
		$srv_cardinality->{$nm} = "";
	    }
	#print " service name : $nm, resnm = ".$resnames->{$nm}." , cardinality = $cardnl \n";	
    # hard code ecm_data_ver to 1
    #em_result format
    #  ecm_data_version|database_name|service_name|service_type|enabled|tafpolicy|preferred instance list|available instance list|running instance list

	       my $svc_entry = "em_result=1|$dbnm|$nm|$srv_types->{$nm}|$enabled->{$nm}|$tafpolicy->{$nm}|$preflist->{$nm}|$availlist->{$nm}|$runlist[$i]|$clusternm|$srvgrp->{$nm}|$resnames->{$nm}|$srv_cardinality->{$nm}|$cardnl|$dbtype\n";
		   push(@all_services, $svc_entry);
	       $i++;
	    } # for each nm
    } # for each dbnm
	
	EMD_PERL_DEBUG("The recordset:\n"); 
	my $record = "";
	foreach $record(@all_services)
	{
	    EMD_PERL_DEBUG($record);
		print $record;
        print "------ \n";
	}
}  # end of script


# Following are subroutines for adding server pool information
# in mgmt_rac_services.
# mgmt_rac_services subroutines START

# Adds a record for the database service in mgmt_rac_services.
# Currently the following attributes do not apply and thus 
# store dummy values:
# enabled 
# tafpolicy 
# pref_list
# availibility
# runlist
# cardinality
sub add_database_service_record
{
	my($dbnm, $dbhom, $clusternm, $dbtype) = @_;
	my @mgmt_racsvc_params = get_mgmt_racsvc_params($dbnm, $dbhom);
	my $enabled = "true";
	my $tafpolicy = "NONE";
	my $pref_list = "";
	my $availibility = "";
	my $runlist = "";
	my $srvpool = $mgmt_racsvc_params[0];
	my $cardinality_type = $mgmt_racsvc_params[1];
	my $cardinality = 0;

	my $record = "em_result=1|$dbnm|$dbnm|internal|true|$tafpolicy|$pref_list|$availibility|$runlist|$clusternm|$srvpool|ora.$dbnm.$dbnm.svc|$cardinality_type|$cardinality|$dbtype\n";
	EMD_PERL_DEBUG("mgmt_rac_services record for database service:\n$record");
	$record;
}

sub get_srvpool_cardinality
{
    my ($dbhome) = @_;
    my $pool_hash = {};
    my $result = run_command($dbhome, "srvctl status srvpool -S 1");
    parse_pool_data($result);
}

sub parse_pool_data
{
    my($input) = @_;
    my @cmd_lines = split("\n", $input);
    my $line = "";
    my %srvpool_info = ();
    foreach $line (@cmd_lines)
    {
	my @toks = split(" ", $line);
	my @tok_list = grep(/res_name={.*}/, @toks);
	my $pool_name = "";
	if(@tok_list == 1)
	{
	    $tok_list[0] =~ /res_name={(.*)}/;  
	    $pool_name = $1;
	}

	@tok_list = grep(/active_servers={.*}/, @toks);
	my $pool_active_cardinality = 0;
	if(@tok_list == 1)
	{
	    $tok_list[0] =~ /active_servers={(.*)}/;
	    my @active_servers = split(",", $1);
	    $pool_active_cardinality = @active_servers;  
        }
	$srvpool_info{$pool_name} = $pool_active_cardinality;
    }
    my @arr = %srvpool_info;
    EMD_PERL_DEBUG("Server pool information hash contents @arr");
    return(%srvpool_info);
}

sub run_command
{
    my ($dbhome, $command) = @_;

    my $config_cmd = '';
    my $result = '';

    $config_cmd = $dbhome."/bin/".$command;
    print($config_cmd);
    EMD_PERL_DEBUG( "run_command: srvctl command $config_cmd  \n");

    my $saveOraHome = $ENV{ORACLE_HOME};
    $ENV{ORACLE_HOME} = $dbhome;
    chomp ($result = `$config_cmd`);
    if ($? != 0)
    {
       	$ENV{ORACLE_HOME} = $saveOraHome;
	my $errormsg = "Failed to run command ".$config_cmd." in run_command(). Return value - $?.\n";
	print($errormsg);
	EMD_PERL_DEBUG($errormsg);
       	return undef;
    }
    $ENV{ORACLE_HOME} = $saveOraHome;

    my $err= has_errcode($result);
    if ($err != 0)
    {
        EMD_PERL_DEBUG( "run_command(): error codes found in the srvctl result : $result \n");
        return undef;
    }
    return $result;
}

sub parse_db_config
{
	my($line) = @_;
	my @result = ("", "");

	if($line=~/(db_type={POLICY_MANAGED})/)
	{
		$result[1] = "UNIFORM";
		if($line=~/srvpool={(.*)} db_type/)
		{
			$result[0] = $1;
		}
	}
	return ($result[0], $result[1]);
}

# Retrieves server pools for a given database as
# comma seperated list in result[0] something like
# "racPool1,racPool2". Retrieves db service cardinality
# type in result[1], either UNIFORM or "". If db type
# is ADMIN_MANAGED, cardinality type is set to "".
# Also, If  database type is ADMIN_MANAGED, server pool
# list is empty
sub get_srvpool_param
{
	my($dbhm, $cmd) = @_;

	my $result = run_command($dbhm, $cmd);
	parse_db_config($result);
}

# Returns an array where index [0] contains server pool
# data and [1] contains cardinality type. For ADMIN_MANAGED
# databases, index [0] will have the value "".
sub get_mgmt_racsvc_params
{
    my($dbname, $dbhome) = @_;
    my $cmd = "srvctl config database -d ".$dbname." -S 1";
    my @mgmt_racsvc_params = get_srvpool_param($dbhome, $cmd);
	if($mgmt_racsvc_params[1] eq "UNIFORM")
	{
		$mgmt_racsvc_params[0] = setup_pool_maxsizes(\@mgmt_racsvc_params, $dbhome);
	}
    EMD_PERL_DEBUG( "get_mgmt_racsvc_params(): For database $dbname, Server Pools: $mgmt_racsvc_params[0] , Cardinality Type: $mgmt_racsvc_params[1].\n");
    return(@mgmt_racsvc_params);
}

sub setup_srvpool_config
{
        my($input, $pools) = @_;
        my @poolnms = split(",", $pools);
        my @cmd_lines = split("\n", $input);
        my $line = "";
	my $pool_names = "";
        my $srv_cnt= "";
        foreach $line (@cmd_lines)
        {
                my $poolnm = "";
                foreach $poolnm(@poolnms)
                {
                        if($line=~/res_name={.*$poolnm}/)
                        {
                                if($line=~ /active_servers={(.*)} online/)
                                {
                                	if($srv_cnt ne "")
                                	{
                                        	$srv_cnt .= ",";
                                	}

					if($1 ne "")
                                        {
                                         	my @active_srvs = split(",", $1);
						$srv_cnt .= @active_srvs;
                                        } else {
						$srv_cnt .= 0;
					}
                                }

                                if($pool_names ne "")
                                {
                                        $pool_names .= ",";
                                }
                                $pool_names.="ora.".$poolnm;
                        }
                }
        }
        $pool_names.":".$srv_cnt;
}

# Appends the pool max sizes to the server pool
# list, something like - racPool1,racPool2:6,4
sub setup_pool_maxsizes
{
	my @racsvc_params = @{$_[0]};
        my $dbhome = $_[1];
	my $cmd = "srvctl status srvpool -S 1";
	my $result = run_command($dbhome, $cmd);
	return(setup_srvpool_config($result, $racsvc_params[0]));
}
# mgmt_rac_services subroutines END

sub get_database_config
{
    my ($dbName, $dbhome) = @_;

    my $config_cmd = '';
    my $result = '';

    $config_cmd = "$dbhome/bin/srvctl config database -S 1 -d ".$dbName ;

#    print "Srvctl command: $config_cmd\n";
    EMD_PERL_DEBUG( "get_database_config : srvctl command $config_cmd  \n");

    my $saveOraHome = $ENV{ORACLE_HOME};
    $ENV{ORACLE_HOME} = $dbhome;
    chomp ($result = `$config_cmd`);
    if ($? != 0) 
    {
       $ENV{ORACLE_HOME} = $saveOraHome;
       print "Failed to run the srvctl config command in get_service_config $? \n";
   EMD_PERL_DEBUG( "get_service_config : failed to run srvctl config command status $?  \n");
	    return undef;
    }
    $ENV{ORACLE_HOME} = $saveOraHome;

##     print "in getServiceStatus, result : $result.\n";

# check if any error code found in result string else pass on to calling function
    my $err= has_errcode($result);
    if ($err != 0)
    {
        EMD_PERL_DEBUG( "get_service_config : error codes found in the srvctl result : $result \n");
        return undef;
    }
    return $result;
}

# RAC One Node: Parse the Database Type value
sub parseForDbType
{
	my $type = '';
        EMD_PERL_DEBUG( "Input for db type parsing:\n @_ \n");
	foreach(@_) {
		if(/Type/) {
			my @tokens = split(' ', $_);
			$type = pop(@tokens);
		}
	}
	$type;
}

# Usage: get_dbnames()
# Calls: srvctl config 
sub get_dbnames
{
     my $cmd = '';
     my $result = '';

     $cmd = "$ENV{EM_CRS_HOME}/bin/srvctl config" ;

     print "Srvctl command: $cmd\n";
     EMD_PERL_DEBUG( "get_dbnames : srvctl command $cmd  \n");

     my @dbnames = ();
     chomp ($result = `$cmd`);
     if ($? != 0) {
          print "em_error=Failed to run the srvctl command in get_dbnames $? \n";
          EMD_PERL_DEBUG( "em_error=get_dbnames : failed to run srvctl command status $?  \n");
#          print "$result\n";
          return @dbnames;
     }

#    print "in get_dbnames, result : $result.\n";
     @dbnames = split("\n", $result);

#    Get database homes
     my $dbname = '';
     my $dbtype = '';
     my $dbhome = $ENV{EM_CRS_HOME};
     my @dblist = ();
     foreach $dbname (@dbnames)
     {
         my $result2 = '';
         my $cmd2 = "$ENV{EM_CRS_HOME}/bin/srvctl config database -d $dbname" ;
         EMD_PERL_DEBUG( "db config command: srvctl command $cmd2  \n");
         chomp ($result2 = `$cmd2`);
         if (1 != 1) { #$? != 0) {
             print "em_error=Failed to run the srvctl config database command in get_dbnames $? \n";
             EMD_PERL_DEBUG( "em_error=get_dbnames : failed to run srvctl config database command status $?  \n");
#            print "$result\n";
             EMD_PERL_DEBUG( "Failed to get database home, will use crs home  \n");
         }
         else
         {
             my @dblines = split("\n", $result2);
             my $dbline = pop(@dblines);
             EMD_PERL_DEBUG( "db details: $dbline  \n");
             my @dbvalues = split(' ', $dbline);
             my $dbhome = pop(@dbvalues);
	     $dbtype = parseForDbType(@dblines);
	 }

         EMD_PERL_DEBUG( "db name: $dbname, db home: $dbhome, db type: $dbtype  \n");
	 if($dbname eq "onenodedb") {
		$dbtype = "RACOneNode";
	 }
         push(@dblist, "$dbname,$dbhome,$dbtype");
     }

     return @dblist;
}

# Usage: get_service_config(dbName, [sv1...svK])
# Calls: srvctl status service -f -S 1 -d dbName -s sv1,sv2...svK

sub get_service_config
{
    my ($dbName, $dbhome) = @_;

    my $config_cmd = '';
    my $result = '';

    $config_cmd = "$dbhome/bin/srvctl config service -S 1 -d ".$dbName ;

    print "Srvctl command: $config_cmd\n";
    EMD_PERL_DEBUG( "get_service_config : srvctl command $config_cmd  \n");

    my $saveOraHome = $ENV{ORACLE_HOME};
    $ENV{ORACLE_HOME} = $dbhome;
    chomp ($result = `$config_cmd`);
    if ($? != 0) {
       $ENV{ORACLE_HOME} = $saveOraHome;
       print "Failed to run the srvctl config command in get_service_config $? \n";
   EMD_PERL_DEBUG( "get_service_config : failed to run srvctl config command status $?  \n");
#            print "$result\n";
	    return undef;
        }
    $ENV{ORACLE_HOME} = $saveOraHome;

##     print "in getServiceStatus, result : $result.\n";

# check if any error code found in result string else pass on to calling function
    my $err= has_errcode($result);
    if ($err != 0)
    {
        EMD_PERL_DEBUG( "get_service_config : error codes found in the srvctl result : $result \n");
        return undef;
    }
    return $result;
}

# Usage: get_service_status(dbName, [sv1...svK])
# Calls: srvctl status service -f -S 1 -d dbName -s sv1,sv2...svK

sub get_service_status
{
    my ($dbName, $dbhome) = @_;

    my $status_cmd = '';
    my $result = '';

    $status_cmd = "$dbhome/bin/srvctl status service -f -S 1 -d ".$dbName ;

    print "Srvctl command: $status_cmd\n";
    EMD_PERL_DEBUG( "get_service_status : srvctl command $status_cmd  \n");

    my $saveOraHome = $ENV{ORACLE_HOME};
    $ENV{ORACLE_HOME} = $dbhome;
    chomp ($result = `$status_cmd`);
    if ($? != 0) {
       $ENV{ORACLE_HOME} = $saveOraHome;
       print "Failed to run the srvctl config command in get_service_status $? \n";
   EMD_PERL_DEBUG( "get_service_status : failed to run srvctl config command status $?  \n");
#            print "$result\n";
	    return undef;
        }
    $ENV{ORACLE_HOME} = $saveOraHome;

##     print "in getServiceStatus, result : $result.\n";

# check if any error code found in result string else pass on to calling function
    my $err= has_errcode($result);
    if ($err != 0)
    {
        EMD_PERL_DEBUG( "get_service_status : error codes found in the srvctl result : $result \n");
        return undef;
    }
    return $result;
}

sub parse_serviceconfig_res
{
   my ($result, $styp, $alist, $plist, $tfp, $en, $grp, $resnm, $card) = @_;

   my @lines = split("\n", $result);
   my @srv_names;
   my $line = '';

#    print "-------------\n inside parse_serviceconfig_res  \n";

   my $lineno = 0;
   foreach $line (@lines)
    {
#	print " Parsing line $lineno : $line \n";
   EMD_PERL_DEBUG( "parsing srvctl status line $lineno : $line \n");
	# replace " ," with "," before tokenizing i.e t1, t2, t3 will be replaced by t1,t2,t3 
	$line =~ s/, /,/g;
#	print " replaced line : $line \n";

	my $name="";
	my $typ="";
	my $pl="";
	my $al="";
	my $rl="";
	my $tf="";
	my $ct="";
	my $res="";

	# parse config line in format 
	#     @=service[0]: name={servicename1} enabled={true/false} pref={inst_list}
        #     avail={inst_list2} disabled_insts={inst_list3} 
        #     tafpolicy={NONE/BASIC/PRECONNECT} type={internal/user}
	# for trail blazer the format will be as follows
	#     @=result[0]: res_name={..} name={..} enabled={true/false} srvgrp={..} 
	#     cardinality={UNIFORM/SINGLETON} disconnect={false} dbRoles={PRIMARY} 
	#     mgmtPolicy={automatic} dtp={false} aqhaNatification={false} 
        #     failoverType={NONE} failoverMethod={NONE} failoverRetry={0} 
        #     failoverDelay={0} clbGoal={NONE} rlbGoal={NONE} tafPolicy={NONE} 
        #     enabledNodes={n1,n2} disabledNodes={} up={} down={n1,n2}

	if ($line =~ /^#@=service/ or $line =~ /^#@=result/)
	{
            if(isInternalService($line)) 
	    {
		next;
            }
	    my @tokens = split(" ",$line);
	    my $token = '';
	    $name="";
	    my $istb = 0;
	    foreach $token (@tokens)
	    {
#		print " parsing token : $token \n";
#   EMD_PERL_DEBUG( "parsing token $token  \n");

		if ($token =~ /^name=/)
		{
		    $name = parseToken($token);
		    push (@srv_names, $name);
#		     print " parsed service name = $name ";

# res_name is first for TB so need to put it in hash using service name here
# make sure res_name appears in output, for older crs it wont
		    if ($istb == 1)
		    {
		       ${$resnm}->{$name}= $res;
#    print " service = $name, parsed resource name = ".${$resnm}->{$name}."\n";
		    }
		}
# 11.2 onwards type will not be listed so will not be internal services
# we will hard code type as user from 11.2 onwards
		if ($token =~ /^type=/)
		{
		    $typ = parseToken($token);
		    ${$styp}->{$name}= $typ;
#		     print " type = $typ ";
		}
		#parse preferrable instance list
		if ($token =~ /^pref=/)
		{
		   $pl = parseToken($token);
		   ${$plist}->{$name}= $pl;
#		     print " pref = $pl ";
		}
		# parse available instance list
		if ($token =~ /^avail=/)
		{
		   $al = parseToken($token);
		   ${$alist}->{$name}= $al;
		}
		# parse  taf policy
		if ($token =~ /^tafpolicy=/)
		{	
		   $tf = parseToken($token);
		   ${$tfp}->{$name}= $tf;
		}
		# parse  enabled
		if ($token =~ /^enabled=/)
		{
		   $tf = parseToken($token);
		   ${$en}->{$name}= $tf;
		}
		# parse  server group
		if ($token =~ /^srvpool=/)
		{
		   $tf = parseToken($token);
		   ${$grp}->{$name}= $tf;
		}
		# parse  resource Name 
		if ($token =~ /^res_name=/)
		{
		    $res = parseToken($token);
		    $istb = 1;
		}
		# parse  service cardinality
		if ($token =~ /^cardinality=/)
		{
		   $ct = parseToken($token);
		   ${$card}->{$name}= $ct;
		}
	    }
	    if ($istb == 1)
	    {
		$typ = 'user';
		${$styp}->{$name}= $typ;
	    }
        }
#	print "\n------ - ----- \n";

	$lineno++;
    }
    return @srv_names;
}

sub isInternalService
{
   my ($input) = @_;
   my $retval = 0;
   if($input =~ /usage_type={internal}/)
   {
      $retval = 1;
   }
   return $retval;
}

sub parse_servicestat_res
{
   my ($result, $rlist) = @_;

   my @lines = split("\n", $result);
   my $line = '';

#    print "-------------\n inside parse_servicestat_res  \n";

   my $lineno = 0;
   foreach $line (@lines)
    {
#	print " Parsing line $lineno : $line \n";
   EMD_PERL_DEBUG( "parsing srvctl status line $lineno : $line \n");
	# replace " ," with "," before tokenizing i.e t1, t2, t3 will be replaced by t1,t2,t3 
	$line =~ s/, /,/g;
#	print " replaced line : $line \n";

	my $rl="";

	# parse status line in format 
	# #@=result[0]: up={inst_list} down={inst_list2} disabled={inst_list3} 
        #               unknown={inst_list4}
	if ($line =~ /^#@=result/)
	{
	    my @tokens = split(" ",$line);
	    my $token = '';
	    foreach $token (@tokens)
	    {
#		print " parsing token : $token \n";
#   EMD_PERL_DEBUG( "parsing token $token  \n");

		# parse running instance list
		if ($token =~ /^up=/)
		{
		    $rl = parseToken($token);
		    push (@{$rlist}, $rl);
		}
	    }
	}

#	print "\n------ - ----- \n";

	$lineno++;
    }
    return;
}

sub parseToken
{
    my  ($token) = @_;
    my $value="";
        my $s = substr $token,  index($token, "=")+1;
#        print "parseToken : s : $s ";
        $s =~ s/[{}]//g;
#        print "parseToken : s : $s ";
	$value = $s;
    return $value;
}

# Purpose: find following error codes in input string:
#          "PRKP"
#          "PRKH"
#          "PRKO"
#          "CRS"
#          "ORA"
sub has_errcode
{
    my $in_str = $_[0];

#    print "error code detector: $in_str\n";

    if ($in_str =~ /PRKP-/ || $in_str =~ /PRKH-/ || $in_str =~ /PRKO-/ || $in_str =~ /CRS-/ || $in_str =~ /ORA-/) {
        return(-1);  # error mesg
    }
    else {
        return(0);
    }

}

sub get_cluster_size
{
    my $sg_config_cmd = '';
    my $result = '';

    my $olsnodes_cmd = "$ENV{EM_CRS_HOME}/bin/olsnodes -s";

    chomp ($result = `$olsnodes_cmd`);
    if ($? != 0) {
       print "Failed to run the olsnodes command $? \n";
   EMD_PERL_DEBUG( "get_cluster_size : failed to run olsnodes command; status $?  \n");
print "$result\n";
	    return 0;
    }

# check if any error code found in result string else pass on to calling function
    my $err= has_errcode($result);
    if ($err != 0)
    {
        EMD_PERL_DEBUG( "get_cluster_size : error codes found in the olsnodes result : $result \n");
        return 0;
    }

print "get_cluster_size, result = $result \n";

     my @lines = split("\n", $result);
     my $line = '';
     my $lineno = 0;

     foreach $line (@lines)
     {
# if required to take Active servers, modify here to have condition for it
	$lineno++;
     }

     return $lineno;
}
