www.pudn.com > filecollector.rar > FC_TaskProcessor.pm
package FC_TaskProcessor;
###############################################################################
#
# @(#) Perl Module:FC_TaskProcessor
#
# Author(s): JiaXiaoLong
#
# Creation Date: 2002/12/18
#
# Description:This module is design to handle task file - a scheme for data
# data file collection.
#
###############################################################################
use Env qw(NPM_HOME);
use XML::Simple;
use Data::Dumper;
use FC_Collector;
use lib "$NPM_HOME/common/modules";
use DBIs;
use WriteDallog;
##############################################################
#
# Function:new
#
# Input:
#
# Output:
#
# Return value:
#
# Description:create taskprocessor
#
#
#############################################################
sub new{
my ($pkg,$Assistant_Var,$common_msg,$db_para) = @_;
my $taskprocessor=bless{
'Assistant_Var' => $Assistant_Var,
'common_msg' => $common_msg,
'db_para' => $db_para
},$pkg;
return $taskprocessor;
}
##############################################################
#
# Function:read_tskcfg
#
# Input:task config file ($tskcfg)
#
# Output:
#
# Return value:
# return code: 1 success ; -1 fail
# structure of prepare and analysis region,
# structure of workflow region, structure of prime
# command region.
#
#
# Description:
#
#
#############################################################
sub read_tskcfg{
my $pkg=shift;
my $tskcfg=shift;
my ($tsk_inf,$workflow,$template);
#-------------------------------------------------
# open task file. It is necessary to write trace
# here if we can't read task file.
#-------------------------------------------------
if(!(-r $tskcfg)){
my $err_msg="Can't read file $tskcfg .\n File:".__FILE__."\t Line:".__LINE__."\n";
DBIs::Trace("$err_msg");
return (-1,'','','');
}
$tsk_inf=eval{XMLin("$tskcfg")};
if($@){
my $err_msg="$@ File:".__FILE__."\t Line:".__LINE__."\n";
DBIs::Trace("$err_msg");
return (-1,'','','');
}
$workflow=$tsk_inf->{'Task_Information'}{'Task_Flow_Region'};
#print "workflow:\n",Dumper($workflow);
$template=$tsk_inf->{'Task_Information'}{'Collect_Config_Template'};
#print "template:\n",Dumper($template);
my $vendor_path = $tsk_inf->{'Vendor_path'};
my $vendor_module = $tsk_inf->{'Vendor_module'};
DBIs::Trace("read $tskcfg success.\n");
return(1,$workflow,$template,$vendor_path,$vendor_module);
}
##############################################################
#
# Function:execute_workflow
#
# Input: structure of workflow($workflow), AssisVar_hdl
# structure of template and structure of prime commands.
#
# Output:
#
# Return value:return_code: 1 success -1 fail.
#
# Description:this function reads task config file and calls
# AssisVar_hdl to finish each step.
#
#############################################################
sub execute_workflow{
my ($pkg,$workflow,$vendor_hdl,$template)=@_;
my ($return_code,$err_msg,$tmp_step_list,$step_list);
#--------------------------------------------------
# If there is only one step in work flow.It is necessary
# to change the step list structure here.
#--------------------------------------------------
$tmp_step_list=$workflow->{'Task'};
$step_list = $pkg->Format_HashStruc($tmp_step_list);
#--------------------------------------------------
# execute each step here.
#--------------------------------------------------
foreach $step_index (sort{$a<=>$b} keys %$step_list){
my $current_step_inf=$step_list->{"$step_index"};
my $action=$current_step_inf->{'action'};
my $child_part_step = $current_step_inf->{'step'};
$child_part_step=$pkg->Format_HashStruc($child_part_step);
my $col_file = $current_step_inf->{'file'};
#-----------------------------------------------
# if action is 'assis_var' , $vendor_hdl will call fuction
# to write $vendor_hdl->{'Assistant_Var'};
#-----------------------------------------------
if($action=~/assis_var/i){
foreach my $step_id (sort{$a<=>$b} keys %$child_part_step){
my $step_info = $child_part_step->{$step_id};
my $input = $step_info->{'input'};
$input =$pkg->Format_HashStruc($input);
my $output = $step_info->{'output'};
$output =$pkg->Format_HashStruc($output);
my $function = $step_info->{'fuction'};
DBIs::Trace("Action: Assis_var\n");
DBIs::Trace("Func: $function()\n");
my $Assis_Var = $vendor_hdl->{'Assistant_Var'};
my $Assis_Var_tmp = eval(Dumper($Assis_Var));
my $db_para = eval(Dumper($vendor_hdl->{'db_para'}));
delete $vendor_hdl->{'Assistant_Var'};
delete $vendor_hdl->{'db_para'};
($return_code,$Assis_Var)= $vendor_hdl->$function($input,$output,$Assis_Var,$db_para);
if($return_code!=1){
DBIs::Trace("task_step: $step_index action: $function FAIL \n");
return -1;
}
if (!$Assis_Var) {
$Assis_Var= $Assis_Var_tmp;
}
$vendor_hdl->{'Assistant_Var'} = $Assis_Var;
$vendor_hdl->{'db_para'} = $db_para;
DBIs::Trace("task_step: $step_index action: $function SUCCESS \n");
}
}
#---------------------------------------------------
# if $action is 'collect' , $vendor_hdl will call fuction
# 'collect_data' to finished collecting ...
#---------------------------------------------------
if($action=~/collect/i){
DBIs::Trace("Action: Collect\n");
my ($colcfg_ref,$cmd_region_temp,$counter);
$colcfg_ref = eval(Dumper($template));
$cmd_region_temp = $colcfg_ref->{'Command_Region'}{'Template'};
delete $colcfg_ref->{'Command_Region'}{'Template'};
$counter=1;
#-----------------------------------
# Write Col_cfg with Assistant_Var
#-----------------------------------
foreach my $step_id (sort{$a<=>$b} keys %$child_part_step){
my $AssisVar = $vendor_hdl->{'Assistant_Var'};
my $step_info = $child_part_step->{$step_id};
($colcfg_ref,$counter) = $pkg->WriteCfg_ref($colcfg_ref,$cmd_region_temp,$step_info,$counter,$AssisVar);
}
eval{XMLout($colcfg_ref,outputfile=>"$col_file",rootname=>"Collect_Config")};
if($@){
DBIs::Trace("collect step error.\n$@\n");
return -1;
}
$pkg->format_xmlfile($col_file);
eval{XMLin($col_file)};
if($@) {
DBIs::Trace("File: $col_file ERROR on XMLin() !!! \n");
return -1;
}
DBIs::Trace("File: $col_file \n");
DBIs::Trace("Write ColCfg_file successfully! now collecting...\n\n");
#---------------------------------
# Collect data by the $col_file
#---------------------------------
($return_code,$err_msg)=$vendor_hdl->collect_data($col_file);
if($return_code!=1){
DBIs::Trace("task_step: $step_index FAIL \n");
DBIs::Trace("Error: $err_msg \n",1);
return -1;
}
DBIs::Trace("task_step: $step_index action: collect data SUCCESS \n");
}
}
#------------------------------------------------------------
# distory all Handles of vendor_modules and Net::Telnet...
#------------------------------------------------------------
my $connect_hdl = $vendor_hdl->{'connect_handle'};
if ($connect_hdl =~ /Telnet/) {
$connect_hdl = $connect_hdl->close();
}
my $writelog_hdl = $vendor_hdl->{'ErrMessage_hdl'};
if ($writelog_hdl =~ /WriteDallog/) {
$writelog_hdl = $writelog_hdl->close();
}
$vendor_hdl = $vendor_hdl->close();
#---------------------------
# Collector Success.
#---------------------------
DBIs::Trace("execute task workflow success \n");
return 1;
}
##############################################################
#
# Function:task_process
#
# Input:task file
#
# Output:
#
# Return value:1 success,-1 error.
#
# Description: this function controls each step of data file
# collection.The main steps are: filling template file
# to create configfile,collecting data, analysising data
# collected and creating new command,etc.
#
#############################################################
sub task_process{
my $pkg=shift;
my $tskcfg=shift;
my $Assistant_Var = $pkg->{'Assistant_Var'};
my $common_msg = $pkg->{'common_msg'};
my $db_para = $pkg->{'db_para'};
delete $pkg->{'common_msg'};
delete $pkg->{'Assistant_Var'};
delete $pkg->{'db_para'};
my ($return_code,$workflow,$template,$vendor_path,$vendor_module,$vendor_hdl);
DBIs::Trace("Start processing task file: $tskcfg...\n\n");
#----------------------------------------------
# read task file, get task flow ¡¢collection
# config template and prime commands.
#----------------------------------------------
($return_code,$workflow,$template,$vendor_path,$vendor_module)=$pkg->read_tskcfg($tskcfg);
if($return_code!=1){
DBIs::Trace("Read taskfile: $tskcfg error. \n");
return $pkg->move_tskcfg(-1,$tskcfg);
}
DBIs::Trace("Read taskfile: $tskcfg successfully. \n");
#----------------------------------------------
# Create Vendors module Handle
#----------------------------------------------
my $WriteDallog_hdl;
if ($common_msg) {
$WriteDallog_hdl = WriteDallog->new($common_msg);
}
else {
$WriteDallog_hdl =0;
}
eval{
push @INC,$vendor_path;
require "$vendor_module.pm";
$vendor_hdl = $vendor_module->new($Assistant_Var,$WriteDallog_hdl,$db_para);
};
if ($@) {
DBIs::Trace("Create objects of $vendor_module.pm fail:$@"." FILE: ".__FILE__." Line:".__LINE__."\n",1,1030214,$pkg->{'task_id'});
exit(-1);
}
#---------------------------------------------------
# execute each step of workflow
#---------------------------------------------------
while(1){
$return_code=$pkg->execute_workflow($workflow,$vendor_hdl,$template);
if($return_code!=1){
DBIs::Trace("Execute task workflow fail.\n");
return $pkg->move_tskcfg(-1,$tskcfg);
}
#---------------------------------------------------
# success.It is necessary to write trace here.
#---------------------------------------------------
DBIs::Trace("Execute taskfile $tskcfg successfully \n");
return $pkg->move_tskcfg(1,$tskcfg);
}
}
##############################################################
#
# Function:move_tskcfg
#
# Input:return_code, task config file
#
# Output:
#
# Return value:return_code
#
# Description:called by sub task_process
# move task config file($tskcfg) to
# different path according to return_code
#
#
#############################################################
sub move_tskcfg{
my ($pkg,$return_code,$tskcfg)=@_;
#----------------------------------------
# get tskcfg's upper path.
#----------------------------------------
$tskcfg=~/(.*)\/new/;
my $upper_path=$1;
if($return_code==1){
DBIs::Trace("mv $tskcfg $upper_path/success/ \n");
if(!(-d "$upper_path/success/")) {
system("mkdir $upper_path/success/");
}
system ("mv $tskcfg $upper_path/success/");
}
if($return_code==-1){
DBIs::Trace("mv $tskcfg $upper_path/fail/ \n");
if(!(-d "$upper_path/fail/")) {
system("mkdir $upper_path/fail/");
}
system ("mv $tskcfg $upper_path/fail/");}
#need trace here.
return $return_code;
}
##############################################################
#
# Function: Format_HashStruc
#
# Input:
#
# Output:
#
# Return value:
#
# Description:
#
#############################################################
sub Format_HashStruc {
my ($pkg,$hash_ref) = @_;
my $hash;
if(exists $hash_ref->{'id'}){
$hash={"1"=>$hash_ref};
delete $hash_ref->{'id'};
}
else{
if(exists $hash_ref->{'name'}){
$hash={"1"=>$hash_ref};
delete $hash_ref->{'name'};
}
else{
#-----------------------------------------------
# there are more than one steps in the work flow.
#-----------------------------------------------
$hash=$hash_ref;
}
}
return ($hash);
}
##############################################################
#
# Function: format_xmlfile
#
# Input:
#
# Output:
#
# Return value:
#
# Description:
#
###############################################################
sub format_xmlfile {
my ($pkg,$xmlfile) =@_;
open (IN,$xmlfile)||die "can't open file:$xmlfile\n";
my $tmpfile ="/tmp/$$"."_tmp_xmlfile";
open (OUT,">$tmpfile")||die "can't open tmpfile:$tmpfile\n";
while () {
my $lines = $_;
$lines =~ s/name=\"cmd\"//;
$lines =~ s/^\s+\<(\d+)/\t\{'mapping'};
$mapping = $pkg->Format_HashStruc($mapping);
my $temp_id = $step->{'Template'}{'id'};
my $cmd_temp = eval(Dumper($cmd_template->{$temp_id}));
foreach my $map_id (sort{$a<=>$b} keys %$mapping){
my $src_var = $mapping->{$map_id}{'src'};
my $tgt_var = $mapping->{$map_id}{'tgt'};
foreach my $varname (sort{$a<=>$b} keys %$cmd_temp) {
if ($varname =~ /$src_var/i) {
$cmd_temp->{$varname} = $tgt_var;
}
}
}
#------------------------------------
# Step 2: instead of Assistant_Var
#------------------------------------
my $AssisVar_list;
foreach my $cmd_tag (sort{$a<=>$b} keys %$cmd_temp) {
my $cmd_body = $cmd_temp->{$cmd_tag};
if ($cmd_body =~ /\[A_VAR:(\S+)\]/i) {
$AssisVar_list->{$1} = $AssisVar->{$1};
}
}
if ($AssisVar_list) {
my $max_longth=0;
foreach my $varname (sort{$a<=>$b} keys %$AssisVar_list) {
my $curr_longth = @{$AssisVar_list->{$varname}};
if ($curr_longth >= $max_longth) {
$max_longth = $curr_longth;
}
}
for (my $i=0;$i<$max_longth;$i++) {
my $cmd_temp_bak = eval(Dumper($cmd_temp));
foreach my $cmd_tag (sort{$a<=>$b} keys %$cmd_temp_bak) {
if($cmd_temp_bak->{$cmd_tag} =~ /\[A_VAR:(\S+)\]/i) {
my @cmd_str = @{$AssisVar_list->{$1}};
$cmd_temp_bak->{$cmd_tag} =~ s/\[A_VAR:\S+\]/$cmd_str[$i]/;
}
}
$colcfg_ref->{'Command_Region'}{$counter} = eval(Dumper($cmd_temp_bak));
$counter+=1;
}
}else {
$colcfg_ref->{'Command_Region'}{$counter} = eval(Dumper($cmd_temp));
$counter+=1;
}
return($colcfg_ref,$counter);
}
sub close {
my ($pkg) = @_;
undef($pkg);
return($pkg);
}
1;