6 |
## |
## |
7 |
## ---------------------------------------------------------------------------------------- |
## ---------------------------------------------------------------------------------------- |
8 |
## $Log$ |
## $Log$ |
9 |
|
## Revision 1.2 2003/01/20 16:59:48 joko |
10 |
|
## + cosmetics and debugging |
11 |
|
## |
12 |
## Revision 1.1 2003/01/19 01:23:04 joko |
## Revision 1.1 2003/01/19 01:23:04 joko |
13 |
## + new from Data/Transfer/Sync.pm |
## + new from Data/Transfer/Sync.pm |
14 |
## |
## |
15 |
## ---------------------------------------------------------------------------------------- |
## ---------------------------------------------------------------------------------------- |
16 |
|
|
17 |
|
|
18 |
package Data::Transfer::Sync::API; |
package Data::Transfer::Sync::API; |
19 |
|
|
20 |
use strict; |
use strict; |
21 |
use warnings; |
use warnings; |
22 |
|
|
23 |
use mixin::with qw( Data::Transfer::Sync ); |
use mixin::with qw( Data::Transfer::Sync ); |
24 |
|
|
25 |
|
|
26 |
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - main |
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - main |
27 |
|
|
28 |
use Data::Dumper; |
use Data::Dumper; |
29 |
|
|
30 |
use Data::Compare::Struct qw( getDifference isEmpty ); |
use Data::Compare::Struct qw( getDifference isEmpty ); |
31 |
use Data::Transform::Deep qw( merge ); |
use Data::Transform::Deep qw( merge ); |
32 |
|
|
33 |
# get logger instance |
# get logger instance |
34 |
my $logger = Log::Dispatch::Config->instance; |
my $logger = Log::Dispatch::Config->instance; |
35 |
|
|
36 |
sub _init { |
sub _init { |
37 |
my $self = shift; |
my $self = shift; |
38 |
} |
} |
39 |
|
|
40 |
sub checkOptions { |
sub checkOptions { |
41 |
my $self = shift; |
my $self = shift; |
42 |
my $opts = shift; |
my $opts = shift; |
58 |
return $result; |
return $result; |
59 |
|
|
60 |
} |
} |
61 |
|
|
62 |
sub checkOptionsV2 { |
sub checkOptionsV2 { |
63 |
my $self = shift; |
my $self = shift; |
64 |
|
|
84 |
|
|
85 |
} |
} |
86 |
|
|
87 |
|
|
88 |
sub prepareOptions { |
sub prepareOptions { |
89 |
|
|
90 |
my $self = shift; |
my $self = shift; |
178 |
return 1; |
return 1; |
179 |
|
|
180 |
} |
} |
181 |
|
|
182 |
sub prepareOptionsV2 { |
sub prepareOptionsV2 { |
183 |
|
|
184 |
my $self = shift; |
my $self = shift; |
196 |
} |
} |
197 |
|
|
198 |
# inform user about option preparation |
# inform user about option preparation |
199 |
$logger->notice( __PACKAGE__ . "->prepareOptionsV2( mode='$opts->{process}->{mode}', source->node='$opts->{source}->{nodeName}', target->node='$opts->{target}->{nodeName}', erase='$opts->{process}->{erase}', prepare='$opts->{process}->{prepare}' )"); |
$logger->notice( __PACKAGE__ . "->prepareOptionsV2( source.node='$opts->{source}->{nodeName}', target.node='$opts->{target}->{nodeName}', mode='$opts->{process}->{mode}', e='$opts->{process}->{erase}', p='$opts->{process}->{prepare}' )"); |
200 |
|
|
201 |
# try to load mapping-metadata-container |
# try to load mapping-metadata-container |
202 |
#my $mapObject = getNewPerlObjectByPkgName($opts->{map}->{moduleName}); |
#my $mapObject = getNewPerlObjectByPkgName($opts->{map}->{moduleName}); |
243 |
return 1; |
return 1; |
244 |
|
|
245 |
} |
} |
246 |
|
|
247 |
|
|
248 |
sub configure { |
sub configure { |
249 |
my $self = shift; |
my $self = shift; |
250 |
my @args = @_; |
my @args = @_; |
281 |
$self->{state}->{configured} = 1; |
$self->{state}->{configured} = 1; |
282 |
return 1; |
return 1; |
283 |
} |
} |
284 |
|
|
285 |
|
sub _getDirectedArrow { |
286 |
|
my $self = shift; |
287 |
|
my $mode = shift; |
288 |
|
$mode ||= ''; |
289 |
|
|
290 |
|
if (lc $mode eq 'push') { |
291 |
|
return '->'; |
292 |
|
} elsif (lc $mode eq 'pull') { |
293 |
|
return '<-'; |
294 |
|
} elsif (lc $mode eq 'full') { |
295 |
|
return '<->'; |
296 |
|
} else { |
297 |
|
return ''; |
298 |
|
} |
299 |
|
} |
300 |
|
|
301 |
# TODO: some feature to show off the progress of synchronization (cur/max * 100) |
# TODO: some feature to show off the progress of synchronization (cur/max * 100) |
302 |
sub syncNodes { |
sub syncNodes { |
303 |
|
|
318 |
$self->{meta} = {}; |
$self->{meta} = {}; |
319 |
|
|
320 |
# hash to sum up results |
# hash to sum up results |
321 |
my $direction_arrow = ''; |
# TODO: re-implement! (sync-statistics???) |
322 |
|
|
323 |
# detect synchronization method to determine which optical symbol (directed arrow) to use |
# detect synchronization method to determine which optical symbol (directed arrow) to use |
324 |
if (lc $self->{args}->{direction} eq 'push') { |
my $mode = $self->{args}->{mode}; # V1 |
325 |
$direction_arrow = '->'; |
$mode ||= $self->{options}->{process}->{mode}; # V2 |
326 |
} elsif (lc $self->{args}->{direction} eq 'pull') { |
my $direction_arrow = $self->_getDirectedArrow($mode); |
|
$direction_arrow = '<-'; |
|
|
} elsif (lc $self->{args}->{direction} eq 'full') { |
|
|
$direction_arrow = '<->'; |
|
|
} else { |
|
|
} |
|
327 |
|
|
328 |
print Dumper($self); |
if (!$self->{options}->{metadata}->{version} || $self->{options}->{metadata}->{version} < 0.2) { |
|
#exit; |
|
|
|
|
|
if (!$self->{metadata}->{version} || $self->{metadata}->{version} < 0.2) { |
|
329 |
$self->_buildMetadataV1(); |
$self->_buildMetadataV1(); |
330 |
} else { |
} else { |
331 |
$self->_buildMetadataV1(); |
$self->_buildMetadataV2(); |
|
#$self->_buildMetadataV2(); |
|
332 |
} |
} |
333 |
|
|
334 |
|
$logger->info( __PACKAGE__ . "->syncNodes: source=$self->{meta}->{source}->{dbKey}/$self->{meta}->{source}->{nodeName} [$self->{meta}->{source}->{nodeType}] $direction_arrow target=$self->{meta}->{target}->{dbKey}/$self->{meta}->{target}->{nodeName} [$self->{meta}->{target}->{nodeType}]" ); |
335 |
|
|
336 |
|
return if !$self->_buildFieldmappingV1(); |
337 |
|
return if !$self->_handleNodeContainers(); |
338 |
|
return if !$self->_prepareSync(); |
339 |
|
|
340 |
#print Dumper($self); |
#print Dumper($self); |
341 |
|
#print Dumper($self->{args}); |
342 |
|
#print Dumper($self->{options}); |
343 |
#print Dumper($self->{meta}); |
#print Dumper($self->{meta}); |
344 |
|
#print Dumper($self->{metadata}); |
345 |
|
|
346 |
|
$self->_syncNodes(); |
347 |
|
|
348 |
|
} |
349 |
|
|
|
$logger->info( __PACKAGE__ . "->syncNodes: source=$self->{meta}->{source}->{dbkey}/$self->{meta}->{source}->{node} $direction_arrow target=$self->{meta}->{target}->{dbkey}/$self->{meta}->{target}->{node}" ); |
|
350 |
|
|
351 |
$self->_buildFieldmappingV1(); |
sub _handleNodeContainers { |
352 |
|
my $self = shift; |
353 |
|
|
|
#print Dumper($self->{meta}); |
|
|
|
|
354 |
# check partners/nodes: does partner exist / is node available? |
# check partners/nodes: does partner exist / is node available? |
355 |
foreach my $partner (keys %{$self->{meta}}) { |
foreach my $partner (keys %{$self->{meta}}) { |
356 |
|
|
357 |
# 1. check partners & storages |
# 1. check partners & storages |
358 |
if (!$self->{meta}->{$partner}) { |
if (!$self->{meta}->{$partner}) { |
359 |
$logger->critical( __PACKAGE__ . "->syncNodes: Could not find partner '$partner' in configuration metadata." ); |
$logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not find partner '$partner' in configuration metadata." ); |
360 |
return; |
next; |
361 |
} |
} |
362 |
|
|
363 |
my $dbkey = $self->{meta}->{$partner}->{dbkey}; |
my $dbkey = $self->{meta}->{$partner}->{dbKey}; |
364 |
|
|
365 |
#print Dumper($self->{meta}); |
#print Dumper($self->{meta}); |
366 |
|
|
367 |
if (!$self->{meta}->{$partner}->{storage}) { |
if (!$self->{meta}->{$partner}->{storage}) { |
368 |
$logger->critical( __PACKAGE__ . "->syncNodes: Could not access storage of partner '$partner' (named '$dbkey'), looks like a configuration-error." ); |
$logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not access storage ( partner='$partner', dbKey='$dbkey' ) - configuration-error?" ); |
369 |
return; |
next; |
370 |
} |
} |
371 |
|
|
372 |
# TODO: |
# TODO: |
384 |
# print Dumper($self); |
# print Dumper($self); |
385 |
#print Dumper($self->{meta}->{$partner}); |
#print Dumper($self->{meta}->{$partner}); |
386 |
#print "öö", $self->{meta}->{$partner}->{node}, "\n"; |
#print "öö", $self->{meta}->{$partner}->{node}, "\n"; |
387 |
my $nodename = $self->{meta}->{$partner}->{node}; |
my $nodename = $self->{meta}->{$partner}->{node}; # V1 |
388 |
|
$nodename ||= $self->{meta}->{$partner}->{nodeName}; # V2 |
389 |
# check if nodename is actually a CODEref, execute it to get a mapped/filtered target-nodename |
# check if nodename is actually a CODEref, execute it to get a mapped/filtered target-nodename |
390 |
|
|
391 |
#print "nodename: $nodename", "\n"; |
#print "nodename: $nodename", "\n"; |
392 |
|
|
393 |
$logger->info( __PACKAGE__ . "->syncNodes: Accessing dbType=\"$dbType\", nodename=\"$nodename\"." ); |
$logger->debug( __PACKAGE__ . "->_handleNodeContainers: Accessing dbType=\"$dbType\", nodename=\"$nodename\"." ); |
394 |
|
|
395 |
=pod |
=pod |
396 |
#print "----", ref $nodename, "\n"; |
#print "----", ref $nodename, "\n"; |
400 |
$nodename = $nodename->($nodename); |
$nodename = $nodename->($nodename); |
401 |
} |
} |
402 |
=cut |
=cut |
403 |
|
|
404 |
|
#print Dumper($self); |
405 |
|
|
406 |
|
#print "partner: $partner - nodename: $nodename", "\n"; |
407 |
|
|
408 |
if (!$self->{meta}->{$partner}->{storage}->existsChildNode($nodename)) { |
if (!$self->{meta}->{$partner}->{storage}->existsChildNode($nodename)) { |
409 |
$logger->critical( __PACKAGE__ . "->syncNodes: Could not reach node \"$nodename\" at partner \"$partner\"." ); |
#print "ex", "\n"; |
410 |
return; |
#exit; |
411 |
|
|
412 |
|
if ($partner eq 'target' && $self->{options}->{target}->{autocreateFolders}) { |
413 |
|
if (!$self->{meta}->{$partner}->{storage}->createChildNode($nodename)) { |
414 |
|
$logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not create node '$self->{meta}->{$partner}->{nodeName}\@$self->{meta}->{$partner}->{dbKey}' [$self->{meta}->{$partner}->{nodeType}]." ); |
415 |
|
next; |
416 |
|
} |
417 |
|
} else { |
418 |
|
$logger->critical( __PACKAGE__ . "->_handleNodeContainers: Could not reach node \"$nodename\" at partner \"$partner\"." ); |
419 |
|
next; |
420 |
|
} |
421 |
} |
} |
422 |
|
|
423 |
} |
} |
424 |
|
|
425 |
|
return 1; |
426 |
|
|
427 |
|
} |
428 |
|
|
429 |
|
|
430 |
|
sub _prepareSync { |
431 |
|
my $self = shift; |
432 |
|
|
433 |
# TODO: |
# TODO: |
434 |
# + if action == PUSH: start processing |
# + if action == PUSH: start processing |
435 |
# -+ if action == PULL: swap metadata and start processing |
# -+ if action == PULL: swap metadata and start processing |
436 |
# - if action == FULL: start processing, then swap metadata and (re-)start processing |
# - if action == FULL: start processing, then swap metadata and (re-)start processing |
437 |
|
|
|
#print Dumper($self->{args}); |
|
|
|
|
438 |
# manipulate metainfo according to direction of synchronization |
# manipulate metainfo according to direction of synchronization |
439 |
if (lc $self->{args}->{direction} eq 'push') { |
if (lc $self->{args}->{direction} eq 'push') { |
440 |
# just do it ... |
# just do it ... |
463 |
#print "ERASE", "\n"; |
#print "ERASE", "\n"; |
464 |
$self->_erase_all('target'); |
$self->_erase_all('target'); |
465 |
} |
} |
466 |
|
|
467 |
$self->_syncNodes(); |
return 1; |
468 |
|
|
469 |
} |
} |
470 |
|
|