Hi,
Recently, one of my customer identified a issue on my probe static_enrichment. Some parts of the SNMP-TRAP QoS was deleted by my probe and not republished on the final message. After few analyse of these QoS i identified that the deleted parts of each PDS was an Array Type ( PDS_PPCH or PDS_PPI type most of the time).
First i was thinking that my method to transform an Hash into a PDS introduced a issue (but no ! ).
My problem was at the level of PDS->asHash() method. asHash() only return the first "key" value of each PDS array.
Take this example :
use strict;
use Data::Dumper;
use lib "/opt/nimsoft/perllib";
use lib "/opt/nimsoft/perl/lib";
use Nimbus::API;
use Nimbus::PDS;
my $PDS = Nimbus::PDS->new();
$PDS->putTable('STR_ARRAY', 'hello', PDS_PCH);
$PDS->putTable('STR_ARRAY', 'world!', PDS_PCH);
$PDS->putTable('INTEGER_ARRAY', '5', PDS_INT);
$PDS->putTable('INTEGER_ARRAY', '10', PDS_INT);
$PDS->dump();
print Dumper($PDS->asHash())."\n";
It produce the following output :
STR_ARRAY PDS_PPCH 25
0 PDS_PCH 6 hello
1 PDS_PCH 7 world!
INTEGER_ARRAY PDS_PPI 17
0 PDS_I 2 5
1 PDS_I 3 10
$VAR1 = {
'STR_ARRAY' => '0',
'INTEGER_ARRAY' => '0'
};
Yeah ... Not really what we want right?
So i started a refactoring of the asHash method in the PDS.pm file. Take a look at my newest version :
1. Renaming of variables because original one was not clear at all...
2. Optimize code
3. Change nimLog level (2 is not enougth for a "debug" / "info" statment). Four should be the best value for me ...
use constant {
PDS_PPCH => 8,
PDS_PPI => 3
};
sub asHash {
my $self = shift;
my $hptr = shift || {};
my $pds = shift || $self->{pds};
my $lev = shift || 1;
my ($rc, $key, $type, $s, $value);
my $line = "-" x $lev;
while($rc == 0) {
($rc, $key, $type, $size, $value) = pdsGetNext($pds);
next if $rc != PDS_ERR_NONE;
# print "PDS Type => $type, key => $key, value => $value, size => $size\n";
if ($type == PDS_PDS) {
if (!defined($hptr->{$key})) {
nimLog(3,"PDS::asHash $line>Adding PDS: $key\n");
$hptr->{$key} = {};
}
asHash($self, $hptr->{$key}, $value, $lev + 1);
pdsDelete($value);
}
elsif ($type == PDS_PPCH || $type == PDS_PPI) {
nimLog(3,"PDS::asHash $line>Adding Array: $key\n");
my $tableIndex = 0;
my @tableValues = ();
my ($rc_table, $rd);
WPDS_PCH: while($rc_table == 0) {
($rc_table, $rd) = pdsGetTable($pds, PDS_PCH, $key, $tableIndex);
last WPDS_PCH if $rc_table != PDS_ERR_NONE;
push(@tableValues, $rd);
$tableIndex++;
};
$hptr->{$key} = \@tableValues;
}
else {
nimLog(3, "PDS::asHash $line>Adding key/value: $key = $value");
$hptr->{$key} = $value;
}
};
return $hptr;
}
At first there is two new PDS Constants to add to the SDK ( INT 8 for PDS_PPCH and INT 3 for PDS_PPI ). After that the only thing to do is to add a new elsif to match these two types !
There is some cases not supported (Like PDS_PDS in PDS_PPCH or things like that). I think it should be possible to add a support for PDS_PPDS type too ...
Note : The Nimbus::PDS::getTable is useless and doesn't work as expected too... I will surely rebuild a complete high level PDS class to work with soon !
And now my script stdout is matching my expectation :
$VAR1 = {
'STR_ARRAY' => [
'hello',
'world!'
],
'INTEGER_ARRAY' => [
'5',
'10'
]
};
And there is no more issue with my probe !
Hope this article will help someone one day
Best Regards,
Thomas