Perl SDK - Nimbus::PDS::asHash (Array refactoring)

Document created by Thomas GENTILHOMME Champion on Jan 12, 2018Last modified by Thomas GENTILHOMME Champion on Jan 12, 2018
Version 2Show Document
  • View in full screen mode

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 Nimsoft (Nimbus) lib
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

1 person found this helpful

Attachments

Outcomes