App-Oozie

 view release on metacpan or  search on metacpan

lib/App/Oozie/Run.pm  view on Meta::CPAN

        if ( is_interactive() ) {
            printf "Do you want to kill the duplicate coordinator(s)? Ids: '%s' [yN]: \n",
                        join( q{', '}, @other_instances ),
            ;
            $yesno = <STDIN>;
            chomp $yesno;
        }
        else {
            $logger->warn( 'Not running interactively and there are other instances. The next calls will fail.' );
        }

        my $outbuffer;
        if ( lc $yesno eq 'y' ) {
            for (@other_instances) {
                $logger->info( "Killing oozie coordinator $_" );

                my $command = [
                    ( $self->secure_cluster
                        ? ()
                        : ( $self->execute_as_someone_else
                                            ? ( qw[ sudo -u ], $self->username )
                                            : ()
                            )
                    ),
                    $self->oozie_cli,
                    ($self->secure_cluster ? ('-Doozie.auth.token.cache=false') : ()),
                    job => -kill => $_,
                    (-oozie => $self->oozie_uri),
                    ($self->doas ? (-doas => $self->doas) : ()), #impersonation
                ];

                IPC::Cmd::run(
                    command => $command,
                    verbose => $self->verbose,
                    buffer  => \$outbuffer,
                    timeout => $self->timeout,
                ) or do {
                    $logger->error( "Error encountered when trying to kill old instance $_" );
                    die sprintf 'Error: %s', $outbuffer // '[unknown]';
                };
                $is_killed++;
            }
            $logger->info( 'Coordinator(s) are now killed' );
        }
    }

    push @{ $self->errors }, 'At least one coordinator running under the same name' if ! $is_killed;

    return;
}

sub check_coordinator_function_calls {
    my $self = shift;
    my $skip = shift;
    my $logger = $self->logger;
    # try to predict the value of such things?
    # examples:
    #    ${coord:formatTime(coord:nominalTime(), 'yyyy-MM-dd')}
    #    ${coord:formatTime(coord:nominalTime(), 'HH')}
    #
    my $looks_like_coord_conf = qr< [$][{]coord[:] >xms;
    my %missing;
    my $collector = sub {
        my($h, $key) = @_;
        return if $key ne 'property';
        my $slot = $h->{ $key };
        #
        # this is possibly broken for some cases
        # as it tries to locate stuff in the hairy xml
        # which can be defined in different ways.
        # need to be fixed / extended per wf
        #
        foreach my $name ( keys %{ $slot } ) {
            if ( ! is_hashref $slot->{ $name } ) {
                if (   exists $slot->{name}
                    && exists $slot->{value}
                    && $slot->{value} =~ $looks_like_coord_conf
                ) {
                    $missing{ $slot->{name} } = $slot->{value};
                }
                next;
            }

            next if exists $slot->{ $name }{ action };

            if ( my $val = $slot->{ $name }{ value } ) {
                next if $val !~ $looks_like_coord_conf;
                $missing{ $name } = $val;
                next;
            }
        }
    };

    my $loop_xml_conf_hash;
    $loop_xml_conf_hash = sub {
        my $hash = shift;
        my $cb   = shift;
        foreach my $key ( keys %{ $hash } ) {
            $cb->( $hash, $key );
            my $value = $hash->{ $key };
            $loop_xml_conf_hash->( $value, $cb ) if is_hashref $value;
        }
        return;
    };

    foreach my $conf ( qw(
        workflow.xml
        coordinator.xml
    )) {
        my $abs_path = File::Spec->catfile($self->path, $conf );
        my $raw;
        eval {
            $raw = $self->hdfs->read( $abs_path );
            if ( ! $raw ) {
                my $msg = 'Could not read the workflow file in HDFS: '
                        . 'did you do the deploy first? No data for: %s'
                        ;
                $logger->logdie( sprintf $msg, $abs_path );
            }
            my $xs = XML::LibXML::Simple->new;
            my $oozie_conf = $xs->XMLin( \$raw );
            $loop_xml_conf_hash->( $oozie_conf, $collector );
            1;
        } or do {
            my $eval_error = $@ || 'Zombie error';
            my $log_level = $conf =~ m{ workflow }xms ? 'logdie' : 'warn';
            $logger->$log_level( $eval_error );
            1;
        };
    }

    return if ! %missing;

    my @vars = sort {  lc $a cmp lc $b } grep { ! $skip->{ $_ } } keys %missing;

    if ( ! @vars ) {
        my $what = join ', ', sort keys %missing;
        $self->logger->info( sprintf 'The missing coordinator variables (%s) were manually defined. Skipping ...', $what );
        return;
    }

    my $fyi = join SPACE_CHAR, map { "--define '$_=value'" } @vars;

    print <<"DEFINE";
The oozie workflow you are trying to run has several coordinator function
dependencies in it's configuration, but since you've wanted to execute it as
as type=workflow, they won't be defined and the oozie job will either fail



( run in 2.255 seconds using v1.01-cache-2.11-cpan-5c0b1e786e0 )