[open-ils-commits] r12025 - in trunk/Open-ILS/src/perlmods/OpenILS/Application: . Trigger

svn at svn.open-ils.org svn at svn.open-ils.org
Sat Jan 31 17:04:37 EST 2009


Author: miker
Date: 2009-01-31 17:04:33 -0500 (Sat, 31 Jan 2009)
New Revision: 12025

Modified:
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger.pm
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger/Event.pm
Log:
non-grouped event firing, event locating and grouping

Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger/Event.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger/Event.pm	2009-01-31 21:31:00 UTC (rev 12024)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger/Event.pm	2009-01-31 22:04:33 UTC (rev 12025)
@@ -35,13 +35,38 @@
             $self->id, {
                 flesh => 2,
                 flesh_fields => {
-                    atev    => [ 'event_def' ],
-                    atevdef => [ 'hook' ]
+                    atev    => [ qw/event_def/ ],
+                    atevdef => [ qw/hook env params/ ]
                 }
             }
         ])
     );
 
+    if ($self->event->state eq 'valid') {
+        $self->valid(1);
+    } elsif ($self->event->state eq 'invalid') {
+        $self->valid(0);
+    } elsif ($self->event->state eq 'reacting') {
+        $self->valid(1);
+    } elsif ($self->event->state eq 'reacted') {
+        $self->valid(1);
+        $self->reacted(1);
+    } elsif ($self->event->state eq 'cleaning') {
+        $self->valid(1);
+        $self->reacted(1);
+    } elsif ($self->event->state eq 'complete') {
+        $self->valid(1);
+        $self->reacted(1);
+        $self->cleanedup(1);
+    } elsif ($self->event->state eq 'error') {
+        $self->valid(0);
+        $self->reacted(0);
+        $self->cleanedup(0);
+    }
+
+
+    $self->update_state('found') || die 'Unable to update event state';
+
     my $class = $self->_fm_class_by_hint( $self->event->event_def->hook->core_type );
     
     my $meth = "retreive_" . $class;
@@ -55,14 +80,17 @@
 
 sub cleanup {
     my $self = shift;
+    my $env = shift || $self->environment;
 
+    return $self if (defined $self->cleanedup);
+
     if (defined $self->reacted) {
         $self->update_state( 'cleaning') || die 'Unable to update event state';
         try {
             my $cleanup = $self->reacted ? $self->event->event_def->cleanup_success : $self->event->event_def->cleanup_failure;
             $self->cleanedup(
                 OpenILS::Application::Trigger::ModRunner::Cleanup
-                    ->new( $cleanup, $self->environment )
+                    ->new( $cleanup, $env)
                     ->run
                     ->final_result
             );
@@ -85,7 +113,10 @@
 
 sub react {
     my $self = shift;
+    my $env = shift || $self->environment;
 
+    return $self if (defined $self->reacted);
+
     if ($self->valid) {
         if ($self->event->event_def->group_field) { # can't react individually to a grouped definition
             $self->{reacted} = undef;
@@ -94,7 +125,7 @@
             try {
                 $self->reacted(
                     OpenILS::Application::Trigger::ModRunner::Reactor
-                        ->new( $self->event->event_def->reactor, $self->environment )
+                        ->new( $self->event->event_def->reactor, $env )
                         ->run
                         ->final_result
                 );
@@ -213,6 +244,19 @@
     return $self->{editor};
 }
 
+sub unfind {
+    my $self = shift;
+    return undef unless (ref $self);
+
+    die 'Cannot unfind a reacted event' if (defined $self->reacted);
+
+    $self->update_state( 'pending' ) || die 'Unable to update event state';
+    $self->{id} = undef;
+    $self->{event} = undef;
+    $self->{environment} = undef;
+    return $self;
+}
+
 sub target {
     my $self = shift;
     return undef unless (ref $self);
@@ -232,12 +276,30 @@
     $self->editor->xact_begin || return undef;
 
     my $e = $self->editor->retrieve_action_trigger_event( $self->id );
+    $e->start_time( 'now' ) unless $e->start_time;
     $e->update_time( 'now' );
     $e->update_process( $$ );
     $e->state( $state );
-    $self->editor->update_action_trigger_event( $e );
 
-    return $self->editor->xact_commit || undef;
+    $e->clear_start_time() if ($e->state eq 'pending');
+
+    my $ok = $self->editor->update_action_trigger_event( $e );
+    if (!$ok) {
+        $self->editor->xact_rollback;
+        return undef;
+    } else {
+        $ok = $self->editor->xact_commit;
+    }
+
+    if ($ok) {
+        $e = $self->editor->data;
+        $self->event->start_time( $e->start_time );
+        $self->event->update_time( $e->update_time );
+        $self->event->update_process( $e->update_process );
+        $self->event->state( $e->state );
+    }
+
+    return $ok || undef;
 }
 
 sub build_environment {
@@ -251,19 +313,21 @@
         $self->environment->{target} = $self->target;
         $self->environment->{event} = $self->event;
         $self->environment->{template} = $self->event->event_def->template;
+
+        $self->environment->{params}{ $_->param } = eval $_->value for ( @{$self->event->event_def->params} );
     
-        my @env_list = $self->editor->search_action_trigger_environment( { event_def => $self->event->event_def } );
-        my @param_list = $self->editor->search_action_trigger_params( { event_def => $self->event->event_def } );
-    
-        $self->environment->{params}{ $_->param } = eval $_->value for ( @param_list );
-    
-        for my $e ( @env_list ) {
+        for my $e ( @{$self->event->event_def->env} ) {
             my (@label, @path);
             @path = split('.', $e->path) if ($e->path);
             @label = split('.', $e->label) if ($e->label);
     
             $self->_object_by_path( $self->event->target, $e->collector, \@label, \@path );
         }
+
+        if ($self->event->event_def->group_field) {
+            my @group_path = split('.', $self->event->event_def->group_field);
+            my $group_object = $self->_object_by_path( $self->event->target, undef, [], \@group_path );
+        }
     
         $self->environment->{complete} = 1;
     } otherwise {

Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger.pm	2009-01-31 21:31:00 UTC (rev 12024)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Trigger.pm	2009-01-31 22:04:33 UTC (rev 12025)
@@ -7,7 +7,11 @@
 use OpenSRF::AppSession;
 use OpenSRF::Utils::SettingsClient;
 use OpenSRF::Utils::Logger qw/:level/;
+use OpenSRF::Utils qw/:datetime/;
 
+use DateTime;
+use DateTime::Format::ISO8601;
+
 use OpenILS::Utils::Fieldmapper;
 use OpenILS::Utils::CStoreEditor q/:funcs/;
 use OpenILS::Application::Trigger::Event;
@@ -18,4 +22,208 @@
 sub initialize {}
 sub child_init {}
 
+sub create_events_for_object {
+    my $self = shift;
+    my $client = shift;
+    my $key = shift;
+    my $target = shift;
+    my $location = shift;
+
+    my $ident = $target->Identity;
+    my $ident_value = $target->$ident();
+
+    my $editor = new_editor(xact=>1);
+
+    my $hooks = $editor->search_action_trigger_hook([
+        { key       => $key,
+          core_type => $target->json_hint
+        },
+        { idlist    => 1 }
+    ]);
+
+    my %hook_hash = map { ($_->id, $_) } @$hooks;
+
+    my $orgs = $editor->json_query({ from => [ 'actor.org_unit_ancestors' => $location ] });
+    my $defs = $editor->search_action_trigger_event_definition([
+        { hook   => $hooks,
+          owner  => [ map { $_->{id} } @$orgs ],
+          active => 't'
+        },
+        { idlist => 1 }
+    ]);
+
+    for my $def ( @$defs ) {
+
+        my $date = DateTime->now;
+
+        if ($hook_hash{$def->hook}->passive eq 'f') {
+
+            if (my $dfield = $def->delay_field) {
+                if ($target->$dfield()) {
+                    $date = DateTime::Format::ISO8601->new->parse_datetime( clense_ISO8601($target->$dfield) );
+                } else {
+                    next;
+                }
+            }
+
+            $date->add( seconds => interval_to_seconds($def->delay) );
+        }
+
+        my $event = Fieldmapper::action_trigger::event->new();
+        $event->target( $ident_value );
+        $event->event_def( $def->id );
+        $event->run_time( $date->strftime( '%G %T%z' ) );
+
+        $event = $editor->create_action_trigger_event( $event );
+
+        $client->respond( $event->id );
+    }
+
+    $editor->commit;
+
+    return undef;
+}
+__PACKAGE__->register_method(
+    api_name => 'open-ils.trigger.event.autocreate',
+    method   => 'create_events_for_object',
+    api_level=> 1,
+    stream   => 1,
+    argc     => 3
+);
+
+
+sub fire_single_event {
+    my $self = shift;
+    my $client = shift;
+    my $event_id = shift;
+
+    my $e = OpenILS::Application::Trigger::Event->new($event_id);
+
+    if ($e->validate->valid) {
+        $e->react->cleanup;
+    }
+
+    return {
+        valid     => $e->valid,
+        reacted   => $e->reacted,
+        cleanedup => $e->cleanedup,
+        event     => $e->event
+    };
+}
+__PACKAGE__->register_method(
+    api_name => 'open-ils.trigger.event.fire',
+    method   => 'fire_single_event',
+    api_level=> 1,
+    argc     => 1
+);
+
+sub run_events {
+    my $self = shift;
+    my $client = shift;
+    my $events = shift; # expects events ready for reaction
+
+    my $env = {};
+    if (ref($events) eq 'ARRAY') {
+        $$evn{target} = [];
+        $$evn{event} = [];
+        for my $e ( @$events ) {
+            for my $evn_part ( keys %{ $e->environment } ) {
+                if ($env_part eq 'target') {
+                    push @{ $$evn{target} }, $e->environment->{target};
+                } elsif ($env_part eq 'event') {
+                    push @{ $$evn{event} }, $e->environment->{event};
+                } else {
+                    push @{ $$evn{$evn_part} }, $e->environment->{$evn_part};
+                }
+            }
+        }
+    } else {
+        $env = $events->environment;
+        $events = [$events];
+    }
+
+    my @event_list;
+    for my $e ( @$events ) {
+        next unless ($e->valid);
+        push @event_list, $e;
+    }
+
+    $event_list[0]->react( $env );
+    $event_list[0]->cleanup( $env );
+
+    return {
+        reacted   => $event_list[0]->reacted,
+        cleanedup => $event_list[0]->cleanedup,
+        events    => @event_list == 1 ? $event_list[0] : \@event_list
+    };
+}
+__PACKAGE__->register_method(
+    api_name => 'open-ils.trigger.event.run_validated',
+    method   => 'fire_single_event',
+    api_level=> 1,
+    argc     => 1
+);
+
+
+sub pending_events {
+    my $self = shift;
+    my $client = shift;
+
+    my $editor = new_editor();
+
+    return $editor->search_action_trigger_event([
+        { state => 'pending', run_time => {'<' => 'now'} },
+        { idlist=> 1 }
+    ]);
+}
+__PACKAGE__->register_method(
+    api_name => 'open-ils.trigger.event.find_pending',
+    method   => 'pending_events',
+    api_level=> 1
+);
+
+
+sub grouped_events {
+    my $self = shift;
+    my $client = shift;
+
+    my ($events) = $self->method_lookup('open-ils.trigger.event.find_pending')->run();
+
+    my %groups = ( '*' => [] );
+
+    for my $e_id ( @$events ) {
+        my $e = OpenILS::Application::Trigger::Event->new($e_id);
+        if ($e->validate->valid) {
+            if (my $group = $event->event->event_def->group_field) {
+
+                # split the grouping link steps
+                my @steps = split '.', $group;
+
+                # find the grouping object
+                my $node = $event->target;
+                $node = $node->$_() for ( @steps );
+
+                # get the pkey value for the grouping object on this event
+                my $node_ident = $node->Identity;
+                my $ident_value = $node->$node_ident();
+
+                # push this event onto the event+grouping_pkey_value stack
+                $groups{$e->event->event_def->id}{$ident_value} ||= [];
+                push @{ $groups{$e->event->event_def->id}{$ident_value} }, $e_id;
+            } else {
+                # it's a non-grouped event
+                push @{ $groups{'*'} }, $e_id;
+            }
+        }
+    }
+
+    return \%groups;
+}
+__PACKAGE__->register_method(
+    api_name => 'open-ils.trigger.event.found_by_group',
+    method   => 'grouped_events',
+    api_level=> 1
+);
+
+
 1;



More information about the open-ils-commits mailing list