File Coverage

blib/lib/Connector/Iterator.pm
Criterion Covered Total %
statement 50 56 89.2
branch 7 10 70.0
condition n/a
subroutine 8 8 100.0
pod 1 1 100.0
total 66 75 88.0


line stmt bran cond sub pod time code
1              
2             use strict;
3 2     2   2685 use warnings;
  2         3  
  2         61  
4 2     2   10 use English;
  2         4  
  2         51  
5 2     2   9 use Moose;
  2         4  
  2         14  
6 2     2   605 use DateTime;
  2         4  
  2         15  
7 2     2   12977 use Data::Dumper;
  2         880752  
  2         89  
8 2     2   18  
  2         4  
  2         968  
9             extends 'Connector';
10              
11             has 'BASECONNECTOR' => ( is => 'ro', required => 1 );
12              
13             # Location must not be used
14             has '+LOCATION' => ( required => 0, 'isa' => 'Undef' );
15              
16             has target => (
17             is => 'rw',
18             isa => 'Undef|ArrayRef',
19             lazy => 1,
20             builder => '_init_target',
21             );
22              
23             has skip_on_error => (
24             is => 'rw',
25             isa => 'Bool',
26             default => 0,
27             );
28              
29              
30             my $self = shift;
31              
32 2     2   5 # the connectors prefix points to the root node of the target list
33             my @target_node = $self->_build_path_with_prefix();
34            
35 2         18 if (!$self->BASECONNECTOR()->exists( \@target_node )) {
36             $self->log()->warn( 'Target node does not exists ' . join(".", \@target_node) );
37 2 50       75 return;
38 0         0 }
39 0         0  
40             $self->log()->debug( 'Node with targets' . Dumper \@target_node );
41            
42 2         47 my @targets = $self->BASECONNECTOR()->get_keys( \@target_node );
43            
44 2         166 if (!scalar @targets) {
45             $self->log()->warn( 'No targets found!' );
46 2 50       10 return;
47 0         0 }
48 0         0
49             $self->log()->debug( 'Targets ' . Dumper \@targets );
50            
51 2         41 return \@targets;
52             }
53 2         150  
54            
55             my $self = shift;
56             my $item = shift;
57             my $data = shift;
58 3     3 1 947  
59 3         11 my $targets = $self->target();
60 3         8
61             if (!$targets) {
62 3         98 $self->log()->error( 'No targets found!' );
63             return $self->_node_not_exists();
64 3 50       14 }
65 0         0
66 0         0 my @item_path = $self->_build_path( $item );
67             $self->log()->debug( 'Item path' . Dumper \@item_path);
68            
69 3         16 # Initialize the base connector
70 3         71 my $baseconn = $self->BASECONNECTOR();
71              
72             my $result;
73 3         208
74             foreach my $target (@{$targets}) {
75 3         16
76             $self->log()->debug( 'Publication to ' . $target . ' with item ' . Dumper $item );
77 3         14
  3         30  
78             my @publication_target = $self->_build_path_with_prefix( [ $target, @item_path ] );
79 4         176
80             $result->{$target} = '';
81 4         226 my $res;
82             if ($self->skip_on_error()) {
83 4         32 eval{ $res = $baseconn->set( \@publication_target , $data ); };
84 4         13 if ($EVAL_ERROR) {
85 4 100       119 $EVAL_ERROR =~ /\A(.{1,200})/;
86 2         6 $result->{$target} = $1;
  2         12  
87 2 100       8 }
88 1         5 } else {
89 1         10 $res = $baseconn->set( \@publication_target , $data );
90             }
91             $self->log()->debug('Publication result: ' . Dumper $res );
92 2         21 }
93              
94 3         100 return $result;
95             }
96              
97 2         166 1;
98              
99              
100              
101             =head1 Name
102              
103             Connector::Iterator
104              
105             =head1 Description
106              
107             Helper to perform a I<set> operation over a list of connector endpoints
108             while handing errors individually for each connector. The return value
109             is a hashref with the processed target names as key and an empty value
110             if no errors occured and the exception message if the target failed. You
111             must set I<skip_on_error> to enable handling of expcetions, otherwise
112             they just bubble up and terminate execution of the loop.
113              
114             Intended use case: write the same data to multiple targets by using
115             multiple connectors. Failed write attemps can be skipped or queued
116             and redone
117              
118             =head2 Supported methods
119              
120             set
121              
122             =head1 Configuration Example
123              
124             my $target = OpenXPKI::Connector::Iterator->new({
125             BASECONNECTOR => $config,
126             PREFIX => $prefix
127             });
128              
129             $target->set( [ $data->{issuer}{CN}[0] ], $data );
130            
131             =head1 OPTIONS
132              
133             =over
134              
135             =item BASECONNECTOR
136              
137             Reference to the connector for the underlying config.
138              
139             =item PREFIX
140              
141             The full path to the node above the targets.
142              
143             =item target
144              
145             List of targets to iterate thru, must be single path elements!
146              
147             =item skip_on_error
148              
149             By default, exceptions from the called connectors bubble up, the loop
150             over the targets terminate. If set, all connectors are processed and
151             any exceptions are returned in the result.
152              
153             =back