File Coverage

blib/lib/Lemonldap/Config/Parameters.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Lemonldap::Config::Parameters;
2 2     2   85921 use strict;
  2         6  
  2         80  
3 2     2   13006 use BerkeleyDB;
  0            
  0            
4             use XML::Simple;
5             use Data::Dumper;
6             use Storable qw (thaw);
7             use LWP::UserAgent();
8              
9             our $VERSION = '3.2.4';
10             our %IPC_CONFIG;
11              
12             # Preloaded methods go here.
13             sub Minus {
14             ## this function convert all key in caMel case into lowercase
15             ## it is a recursive function
16             ## it keeps all the old keys
17             my $rh =shift;
18             foreach (keys %{$rh}) {
19             my $k =$_;
20             return unless $k;
21             if ($k ne lc ($k)) {
22             $rh->{lc($k)} = $rh->{$k} ;
23             }
24             if (ref $rh->{$k}) {
25             Minus ($rh->{$k});
26             }
27             }
28             return ;
29             }
30            
31              
32              
33             sub _getFromCache {
34              
35             my $self = shift;
36             my $cache = $self->{cache};
37             my $cog;
38             my $ttl;
39              
40             tie %IPC_CONFIG, 'BerkeleyDB::Btree',
41             -Filename => $cache ,
42             -Flags => DB_CREATE ;
43             unless ( keys(%IPC_CONFIG) ) {
44              
45             #first I read the xml file
46             $self->_readFile;
47             ## write cache
48             $self->_writeCache;
49             $cog = $self->{config};
50             }
51             else {
52              
53             $ttl = $IPC_CONFIG{TTL};
54             $self->{ttl} = $ttl;
55             #
56             #
57             #
58              
59             if ($ttl=~ /ifmodified/i )
60             {
61             $self->{ttl} =0;
62             $ttl=0;
63             }
64             $self->{available} = $IPC_CONFIG{AVAILABLE};
65             $self->{file} = $IPC_CONFIG{FILE};
66             $self->{agent} = $IPC_CONFIG{SOAPAGENT};
67             $self->{lastmodified} = $IPC_CONFIG{LASTMODIFIED};
68             $self->{method} = $IPC_CONFIG{METHOD};
69             if ( $self->{method} ) {
70             unless ( $self->{i_am_soap_server} ) {
71             $self->{on_same} = $IPC_CONFIG{ON_SAME};
72             }
73              
74             $self->{uri} = $IPC_CONFIG{SOAPURI};
75             $self->{proxy} = $IPC_CONFIG{SOAPPROXY};
76             }
77             my %tmp = %IPC_CONFIG;
78             my $tmpvar = $tmp{config};
79             my $it;
80             $it = eval $tmpvar if $tmpvar;
81             $self->{config} = $it;
82             my $__modif__ = ( stat $self->{file} )[9];
83             if ( $__modif__ ne $self->{lastmodified} )
84             { # the modified timestamp is different i'll force the reload
85             $IPC_CONFIG{AVAILABLE} = 'RELOAD';
86             $self->{lastmodified} = $__modif__;
87             }
88              
89             if ( $IPC_CONFIG{AVAILABLE} eq 'RELOAD' ) {
90             $self->_readFile;
91             $self->_writeCache;
92             $cog = $self->{config};
93             return ($cog);
94             }
95             if ( $IPC_CONFIG{AVAILABLE} eq 'DESTROY' ) {
96             $self->_readFile;
97             $self->_deleteCache;
98             delete $self->{cache};
99             $cog = $self->{config};
100             return ($cog);
101             }
102             $cog = $self->{config};
103              
104             # all is good we must compare time and ttl
105             return ($cog) if ( $self->{ttl} == 0 );
106             my $timenow = time;
107             my $timecalc = $self->{available} + $self->{ttl};
108             if ( $timenow > $timecalc ) { # the cache is too old
109             $self->_readFile;
110             $self->_writeCache;
111              
112             }
113             $cog = $self->{config};
114             return ($cog);
115              
116             }
117             }
118              
119             sub destroy {
120             my $self = shift;
121             $self->_deleteCache;
122             delete $self->{cache};
123             }
124              
125             # function used to manage cache conf from command line
126             sub f_delete {
127             my $arg = shift;
128             unlink ($arg);
129             return (0);
130             }
131              
132             sub f_reload {
133             my $arg = shift;
134              
135             tie %IPC_CONFIG, 'BerkeleyDB::Btree',
136             -Filename => $arg ,
137             -Flags => DB_CREATE ;
138            
139             $IPC_CONFIG{ttl} = '1';
140              
141             $IPC_CONFIG{AVAILABLE} = 'RELOAD';
142              
143             untie %IPC_CONFIG ;
144             return (0);
145             }
146              
147             sub f_dump {
148             my $arg = shift;
149             tie %IPC_CONFIG, 'BerkeleyDB::Btree',
150             -Filename => $arg ,
151             -Flags => DB_CREATE ;
152              
153             $Data::Dumper::Indent = 1;
154             $Data::Dumper::Terse = 1;
155             if ($IPC_CONFIG{'QUEUE'}) { #it's ipc segment for handler cache level 2
156             my $tmpvar = $IPC_CONFIG{'QUEUE'};
157             my @tmp ;
158             if ($tmpvar) {
159             @tmp= split /#/,$tmpvar ;
160             }
161             print "Queue : $#tmp\n";
162             foreach (@tmp) {
163             print "=> $_\n";
164             }
165             print "\n";
166              
167             }
168             my $ligne = Dumper( \%IPC_CONFIG );
169             print "$ligne\n";
170              
171             untie %IPC_CONFIG;
172             return "OK\n";
173             }
174              
175             sub _retrieve_on_soap {
176             my $self = shift;
177             my $uri = shift;
178             my $proxy = shift;
179             my $file = $self->{file};
180             my $glue = $self->{cache};
181             require SOAP::Lite;
182             my $s = SOAP::Lite->uri($uri)->proxy($proxy);
183             my $hl = $s->SOAP::new(
184             file => $file,
185             cache => $glue,
186             );
187              
188             #my $res=$hl->SOAP::retrieve ;
189             return $hl->{config};
190             }
191              
192             sub _readFile {
193             my $self = shift;
194             my ( $uri, $proxy, $obj );
195             my ( $lastmodified, $par, $config );
196             my $file = $self->{file};
197             $self->{lastmodified} = ( stat $self->{file} )[9];
198            
199             my $cache = $self->{cache};
200             $cache = uc $cache if ($self->{i_am_soap_server});
201             my $method = $self->{method}||'NONE';
202             unless ( $self->{i_am_soap_server} ) {
203              
204             if ( $method eq 'SOAP' ) {
205             $uri = $self->{uri};
206             $proxy = $self->{proxy};
207              
208             #unless ($self->{i_am_soap_server}) #the server soap objet must not make soap request on itself
209             my $conf_enc = $self->_retrieve_on_soap( $uri, $proxy );
210             my $conf_decode = thaw($conf_enc);
211             $self->{config} = $conf_decode;
212             $self->_writeCache;
213             ### now a rewrite or write my file on disk
214             ### the soap agent on server must not write file too
215             return 1 if ( $self->{i_am_soap_server} );
216             ### the agent config in soap server must not write file
217             return 1 if ( $self->{on_same} );
218             ## last precaution
219             my $filelock = "$self->{file}.lock";
220             return 1 if ( -e $filelock );
221              
222             my $xml = XMLout($conf_decode);
223             open CONFIG, ">$file" || die "@! $file \n";
224             flock( CONFIG, 2 ); # I lock file
225             print CONFIG $xml;
226             close(CONFIG); # make the unlock
227             return 1;
228              
229             }
230             }
231              
232             $config = XMLin( $file, ForceArray => 1, );
233              
234             # I extract info about the cache ttl
235              
236             my $cache_param = $config->{cache};
237              
238             # there are sereval cache descriptors or one alone
239             #
240             my $__cache__;
241             foreach my $tmp ( keys %{$cache_param} )
242              
243             {
244             if ( $cache_param->{$tmp}{'ConfigIpcKey'} eq $cache ) {
245             $__cache__ = $cache_param->{$tmp};
246             }
247              
248             }
249             $par = $__cache__->{ConfigTtl};
250             if ($par =~ /ismodified/i ) {
251             $par =0;
252             $lastmodified = 1;
253             }
254              
255             $self->{ttl} = $par || '0';
256             $self->{method} = $__cache__->{Method}||'NONE';
257             if ( $self->{method} eq 'SOAP' ) {
258             $self->{uri} = $__cache__->{SoapUri};
259             $self->{proxy} = $__cache__->{SoapProxy};
260             $self->{agent} = $__cache__->{SoapAgent};
261              
262             }
263             # if ( ( $self->{lastmodified} ) and not($lastmodified) ) {
264             # $self->{lasmodified} = 0;
265             # }
266             # else {
267             $self->{lastmodified} = 1 unless $self->{lastmodified};
268             # }
269             ## call Minus function for lowering case
270             Minus($config) ;
271            
272            
273             $self->{config} = $config;
274             1;
275             }
276              
277             sub _deleteCache {
278             my $self = shift;
279             my $cache = $self->{cache};
280            
281             tie %IPC_CONFIG, 'BerkeleyDB::Btree',
282             -Filename => $cache ,
283             -Flags => DB_CREATE ;
284             %IPC_CONFIG ='';
285             untie %IPC_CONFIG;
286             }
287              
288             sub _writeCache {
289             my $self = shift;
290              
291             # unless ( $self->{i_am_soap_server} ) {
292             # return 1
293             # if ( $self->{on_same} )
294             # ; ## the agent config in the soap server must not
295             # ## write in cache , there soap agent does this
296             # return 1
297             # if ( $IPC_CONFIG{ON_SAME} )
298             # ; ## the soap agent may be already write in IPC
299             # #with me it's belt and straps of trousers
300             # my $filelock = "$self->{file}.lock";
301             # return 1 if ( -e $filelock );
302             # }
303              
304             my $time = time;
305             my $cache = $self->{cache};
306             my $config = $self->{config};
307             $Data::Dumper::Purity = 1;
308             $Data::Dumper::Terse = 1;
309             $Data::Dumper::Deepcopy = 1;
310             my $configs = Dumper($config);
311             my $ttl = $self->{ttl};
312             my $lastmodified = $self->{lastmodified};
313             my $file = $self->{file};
314             delete $IPC_CONFIG{config};
315             # %IPC_CONFIG = '';
316             untie %IPC_CONFIG;
317             unlink ($self->{cache});
318             tie %IPC_CONFIG, 'BerkeleyDB::Btree',
319             -Filename => $cache ,
320             -Flags => DB_CREATE ;
321             $IPC_CONFIG{config} = $configs;
322             $IPC_CONFIG{TTL} = $ttl;
323             $IPC_CONFIG{AVAILABLE} = $time;
324             $IPC_CONFIG{FILE} = $file;
325             $IPC_CONFIG{SOAPAGENT} = $self->{agent} if $self->{agent};
326             $IPC_CONFIG{LASTMODIFIED} = $lastmodified if $lastmodified;
327             $IPC_CONFIG{METHOD} = $self->{method} if $self->{method};
328             $IPC_CONFIG{SOAPURI} = $self->{uri} if $self->{uri};
329             $IPC_CONFIG{SOAPPROXY} = $self->{proxy} if $self->{proxy};
330             if ( $self->{method} ) {
331              
332             if ( $self->{i_am_soap_server} )
333             { # the soap server tell that is it for an eventual
334             # agent config in the same machine
335             # I will create a empty lock file for
336             # avoid recursive call between
337             # soap server and agent config
338              
339             $file = "$self->{file}.lock";
340              
341             open LOCK, ">$file";
342             close LOCK;
343             $IPC_CONFIG{ON_SAME} = 1;
344              
345             #now i 'll notice at all agents the modification
346             my @soapagent;
347             my $sp ;
348             my $tt = $self->{agent};
349             $sp =eval $tt;
350             @soapagent = @{$sp};
351             my $glue =uc ($self->{cache});
352             my $ua = LWP::UserAgent->new (timeout => 30);
353             for my $l (@soapagent) {
354             my $res =$ua->get ("$l?glue=$glue");
355              
356             }
357             }
358              
359            
360             }
361             untie %IPC_CONFIG;
362              
363             return 1;
364             }
365              
366             sub new {
367             my $class = shift;
368             my %conf = @_;
369              
370             my $self = bless {
371              
372             },
373             ref($class) || $class;
374             $self->{file} = $conf{file} if $conf{file};
375             $self->{cache} = $conf{cache} if $conf{cache};
376             $self->{i_am_soap_server} = $conf{server} if $conf{server};
377             $self->{cache} = lc $self->{cache} if ($self->{i_am_soap_server});
378             return $self;
379             }
380              
381             sub getDomain {
382             my $self = shift;
383             my $domain = shift;
384             my $config = $self->getAllConfig;
385             unless ($domain) {
386             my $d = ( keys %{ $config->{domain} } );
387             die "Ambigious domain\n" if ( $d != 1 );
388             ($domain) = ( keys %{ $config->{domain} } );
389             }
390              
391             my $cdomain = $config->{domain}{$domain};
392             return ($cdomain);
393              
394             }
395              
396             sub findParagraph {
397             my ( $self, $chapitre, $motif ) = @_;
398             my $config = $self->getAllConfig;
399             my $parag;
400             if ( $chapitre && $motif ) {
401             $parag = $config->{$chapitre}->{$motif};
402             }
403             else {
404             $parag = $config->{$chapitre};
405             }
406             return ($parag);
407             }
408              
409             sub formateLineHash {
410             my ( $self, $line, $motif, $replace ) = @_;
411             my %cf;
412             my $t;
413             if ( $line =~ /^\(/ ) {
414             $t = $line;
415             }
416             else {
417             $t = "($line );";
418             }
419              
420             %cf = eval $t;
421             if ($motif) {
422             for ( values %cf ) {
423             s/$motif/$replace/;
424             }
425             }
426             return ( \%cf );
427             }
428              
429             sub formateLineArray {
430             my ( $self, $line, $motif, $replace ) = @_;
431             my @cf;
432             my $t;
433             if ( $line =~ /^\[/ ) { $t = $line; }
434             else {
435             $t = "[$line ];";
436             }
437             @cf = eval $t;
438             if ($motif) {
439             for (@cf) {
440             s/$motif/$replace/;
441             }
442             }
443             return ( \@cf );
444             }
445              
446             sub getAllConfig {
447             my $self = shift;
448             my $config;
449             my $file = $self->{file};
450             if ( $self->{cache} ) { # cache is available
451             $config = $self->_getFromCache;
452              
453             }
454             else { # cache forbidden
455            
456             $config = XMLin( $file, ForceArray => 1, );
457              
458             Minus($config) ;
459             }
460             unless ($config) { #at the first time
461             $config = XMLin( $file, ForceArray => 1, );
462              
463             Minus($config) ;
464             }
465             return $config;
466             }
467             1;
468             __END__