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