From: Lebbeous Fogle-Weekley Date: Mon, 26 Sep 2011 23:31:01 +0000 (-0400) Subject: now we can validate call files just in time, so we don't ... X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=0c1eb8b49430e321d6ed456a4126b2f601b1fbb3;p=evergreen%2Fequinox.git now we can validate call files just in time, so we don't ... call patrons with bogus overdue notices anymore. Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-allocator.pl b/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-allocator.pl index 7a1b3b9e85..100f2b2ed4 100755 --- a/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-allocator.pl +++ b/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-allocator.pl @@ -79,6 +79,66 @@ Equinox Software, Inc. =cut +package RevalidatorClient; + +use Sys::Syslog qw/:standard :macros/; +use RPC::XML; +use RPC::XML::Client; +use Data::Dumper; + +sub new { + my $self = bless {}, shift; + + $self->setup(@_); + return $self; +} + +sub setup { + my ($self, %config) = @_; + + # XXX error_handler, fault_handler, combined_handler + # such handlers should syslog and die + + $self->{client} = new RPC::XML::Client($config{revalidator_uri}); + $self->{config} = \%config; +} + +sub get_event_ids { + my ($self, $filename) = @_; + + if (not open FH, "<$filename") { + syslog LOG_ERR, "revalidator client could not open $filename"; + die "revalidator client could not open $filename"; + } + + my $result = 0; + while () { + next unless /event_ids = ([\d,]+)$/; + + $result = [ map int, split(/,/, $1) ]; + } + + close FH; + return $result; +} + +sub still_valid { + my ($self, $filename) = @_; + # Here we want to contact Evergreen's open-ils.trigger service and get + # a revalidation of the event described in a given file. + # We'll return 1 for valid, 0 for invalid. + + my $event_ids = $self->get_event_ids($filename) or return 0; + + print STDERR (Dumper($event_ids), "\n") if $self->{config}->{t}; + + return $self->{client}->simple_request("revalidate", $event_ids); +} + +1; + +package main; + use warnings; use strict; @@ -90,13 +150,13 @@ use File::Spec; use Sys::Syslog qw/:standard :macros/; use Cwd qw/getcwd/; -our %config; -our %opts = ( +my %config; +my %opts = ( c => "/etc/eg-pbx-daemon.conf", v => 0, t => 0, ); -our $universal_prefix = 'EG'; +my $universal_prefix = 'EG'; sub load_config { %config = ParseConfig($opts{c}); @@ -165,17 +225,6 @@ sub queue { $opts{v} and print $msg . "\n"; } -sub still_valid { - my ($filename) = @_; - # Here we want to contact Evergreen's open-ils.trigger service and get - # a revalidation of the event described in a given file. - # We'll return 1 for valid, 0 for invalid. - - print STDERR "filename is $filename\n"; # XXX - - return 1; -} - ### MAIN ### getopts('htvc:', \%opts) or pod2usage(2); @@ -216,20 +265,40 @@ if ($limit) { $opts{t} or syslog LOG_NOTICE, "Queue is full ($limit)"; } - # Take as many files from @incoming as it takes to fill up @actually - # with files whose contents describe still-valid events. - for (my $i = 0; $i < $available; $i++) { - while (@incoming) { - my $candidate = shift @incoming; - if (still_valid($candidate)) { - unshift @actually, $candidate; - last; + if ($config{revalidator_uri}) { # USE REVALIDATOR + # Take as many files from @incoming as it takes to fill up @actually + # with files whose contents describe still-valid events. + + my $revalidator = new RevalidatorClient(%config, %opts); + + for (my $i = 0; $i < $available; $i++) { + while (@incoming) { + my $candidate = shift @incoming; + + if ($revalidator->still_valid($candidate)) { + unshift @actually, $candidate; + last; + } else { + my $newpath = ($config{done_path} || "/tmp") . + "/SKIPPED_" . basename($candidate); + + if ($opts{t}) { + print "rename $candidate $newpath\n"; + } else { + rename($candidate, $newpath); + } + } } } + } else { # DON'T USE REVALIDATOR + if ($in_count > $available) { + # slice down to correct size + @actually = @incoming[0..($available-1)]; + } } } -# XXX Even without a limit we should still filter by still_valid() in theory, +# XXX Even without a limit we could still filter by still_valid() in theory, # but in practive the user should always use a limit. if ($opts{v}) { @@ -247,3 +316,4 @@ foreach (@actually) { queue($_); } +1; diff --git a/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-daemon.conf b/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-daemon.conf index e13f444eb2..dbfe0b5406 100644 --- a/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-daemon.conf +++ b/Open-ILS/src/asterisk/pbx-daemon/eg-pbx-daemon.conf @@ -7,3 +7,4 @@ group asterisk universal_prefix EG01 queue_limit 30 use_allocator 1 +# revalidator_uri http://somehost:12080/ diff --git a/Open-ILS/src/asterisk/revalidator/revalidator-daemon.pl b/Open-ILS/src/asterisk/revalidator/revalidator-daemon.pl new file mode 100755 index 0000000000..f222d2f118 --- /dev/null +++ b/Open-ILS/src/asterisk/revalidator/revalidator-daemon.pl @@ -0,0 +1,96 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +{ + no strict; + no warnings; + require "/openils/bin/oils_header.pl"; +}; + +use RPC::XML::Server; +#use Config::General qw/ParseConfig/; +use Getopt::Long; +use Data::Dumper; +$Data::Dumper::Indent = 0; + +use OpenSRF::Utils::Logger qw/:logger/; + +my %opts = ( + "config-file" => "/openils/conf/opensrf_core.xml", + "port" => 12080 +); + +my $failure = sub { + my $msg = shift; + + $logger->error($msg); + + return new RPC::XML::fault(faultCode => 500, faultString => $msg); +}; + +my $bad_request = sub { + my $msg = shift; + + $logger->warn($msg); + + return new RPC::XML::fault(faultCode => 400, faultString => $msg); +}; + + +sub revalidate { + my $r = simplereq( + "open-ils.trigger", + "open-ils.trigger.event_group.revalidate.test", + @_ + ); + + if (oils_is_event($r)) { + $logger->warn( + "open-ils.trigger.event_group.revalidate.test returned event: " . + Dumper($r) + ); + return 0; + } + + return $r; +} + +sub main { + GetOptions(\%opts, qw/config-file=s port=i/); + + { + no warnings; + no strict; + osrf_connect($opts{"config-file"}); + }; + + my $server; + + if (!($server = new RPC::XML::Server(port => $opts{port}))) { + my $msg = "Failed to get new RPC::XML::Server: $!"; + $logger->error($msg); + die $msg; + } + + $logger->info("RPC::XML::Server started"); + + # Regarding signatures: + # ~ the first datatype is for RETURN value, + # ~ any other datatypes are for INCOMING args + # + # Everything here returns a struct. + + $server->add_proc({ + name => 'revalidate', + code => \&revalidate, + signature => ['int array'] + }); + + $server->add_default_methods; + $server->server_loop; + 0; +} + +main @ARGV; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger.pm index ae83a7755a..69e873387a 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger.pm @@ -600,6 +600,41 @@ __PACKAGE__->register_method( argc => 1 ); +sub revalidate_event_group_test { + my $self = shift; + my $client = shift; + my $events = shift; + + my $e = OpenILS::Application::Trigger::EventGroup->new(@$events); + + my $result = $e->revalidate_test; + + $e->editor->disconnect; + OpenILS::Application::Trigger::Event->ClearObjectCache(); + + return $result; +} +__PACKAGE__->register_method( + api_name => 'open-ils.trigger.event_group.revalidate.test', + method => 'revalidate_event_group_test', + api_level=> 1, + argc => 1, + signature => { + desc => q/revalidate a group of events. + This does not actually update the events (so there will be no change + of atev.state or anything else in the database, unless an event's + validator makes changes out-of-band). + + This returns 1 or 0. It returns 1 if **ANY** event in the group tests + as valid. Otherwise it return 0. + /, + params => [ + {name => "events", type => "array", desc => "list of event ids"} + ] + } +); + + sub pending_events { my $self = shift; my $client = shift; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Event.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Event.pm index de11a15eac..3e98ad7c78 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Event.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Event.pm @@ -227,6 +227,32 @@ sub validate { return $self; } +sub revalidate_test { + my $self = shift; + + if ($self->build_environment->environment->{complete}) { + try { + $self->valid( + OpenILS::Application::Trigger::ModRunner::Validator->new( + $self->event->event_def->validator, + $self->environment + )->run->final_result + ); + } otherwise { + $log->error("Event revalidation failed with ". shift()); + }; + + return 1 if defined $self->valid and $self->valid; + return 0; + } + + $logger->error( + "revalidate: could not build environment for event " . + $self->event->id + ); + return 0; +} + sub cleanedup { my $self = shift; return undef unless (ref $self); diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/EventGroup.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/EventGroup.pm index 2a3c6c632c..cac2129f02 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/EventGroup.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/EventGroup.pm @@ -98,6 +98,26 @@ sub validate { return $self; } +sub revalidate_test { + my $self = shift; + + $self->editor->xact_begin; + + my @valid_events; + try { + for my $event ( @{ $self->events } ) { + push @valid_events, $event if $event->revalidate_test; + } + $self->editor->xact_rollback; + } otherwise { + $log->error("Event group validation failed with ". shift()); + $self->editor->xact_rollback; + }; + + # If any member of the group is valid, return true + return (scalar(@valid_events) > 0 ? 1 : 0); +} + sub cleanedup { my $self = shift; return undef unless (ref $self);