From: Mike Rylander Date: Mon, 28 Oct 2019 15:03:58 +0000 (-0400) Subject: LP#1860703: Create A/T hook and reactor for push integration X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=717029528b9b8cc3bd59dfb89cc20bc680b6fd3d;p=Evergreen.git LP#1860703: Create A/T hook and reactor for push integration There is currently no stock mechanism for pushing information out of Evergreen to trigger activities in external systems. Third party discovery systems, among other external systems, would benefit from the ability to be alerted of changes to data within an Evergreen instance. This commit adds such a capability by supplying a new A/T reactor module that can make HTTP requests that supply data to a third party endpoint. To support the discovery system use case, this commit also adds a new A/T hook, bre.edit, fired whenever a bibliographic record is modified due to staff interaction. Signed-off-by: Mike Rylander Signed-off-by: Troy Leonard Signed-off-by: Galen Charlton --- diff --git a/Open-ILS/src/extras/install/Makefile.debian-buster b/Open-ILS/src/extras/install/Makefile.debian-buster index 4723734221..a561a0a92b 100644 --- a/Open-ILS/src/extras/install/Makefile.debian-buster +++ b/Open-ILS/src/extras/install/Makefile.debian-buster @@ -74,6 +74,7 @@ export DEBS = \ libbz2-dev\ libparse-recdescent-perl\ libhtml-defang-perl\ + libconfig-general-perl\ yaz export DEB_APACHE_MODS = \ diff --git a/Open-ILS/src/extras/install/Makefile.debian-jessie b/Open-ILS/src/extras/install/Makefile.debian-jessie index d30fa4dd25..21c906b96d 100644 --- a/Open-ILS/src/extras/install/Makefile.debian-jessie +++ b/Open-ILS/src/extras/install/Makefile.debian-jessie @@ -75,6 +75,7 @@ export DEBS = \ libbz2-dev\ libparse-recdescent-perl\ libhtml-defang-perl\ + libconfig-general-perl\ yaz export DEB_APACHE_MODS = \ diff --git a/Open-ILS/src/extras/install/Makefile.debian-stretch b/Open-ILS/src/extras/install/Makefile.debian-stretch index d16e1a51bf..e5a9ce596f 100644 --- a/Open-ILS/src/extras/install/Makefile.debian-stretch +++ b/Open-ILS/src/extras/install/Makefile.debian-stretch @@ -74,6 +74,7 @@ export DEBS = \ libbz2-dev\ libparse-recdescent-perl\ libhtml-defang-perl\ + libconfig-general-perl\ yaz export DEB_APACHE_MODS = \ diff --git a/Open-ILS/src/extras/install/Makefile.fedora b/Open-ILS/src/extras/install/Makefile.fedora index e858f98205..43ba4844b1 100644 --- a/Open-ILS/src/extras/install/Makefile.fedora +++ b/Open-ILS/src/extras/install/Makefile.fedora @@ -78,6 +78,7 @@ export CPAN_MODULES = \ Net::Z3950::Simple2ZOOM \ Template::Plugin::POSIX \ SRU \ + Config::General \ Rose::URI export CPAN_MODULES_FORCE = \ diff --git a/Open-ILS/src/extras/install/Makefile.ubuntu-bionic b/Open-ILS/src/extras/install/Makefile.ubuntu-bionic index f1478a308c..519d063381 100644 --- a/Open-ILS/src/extras/install/Makefile.ubuntu-bionic +++ b/Open-ILS/src/extras/install/Makefile.ubuntu-bionic @@ -71,6 +71,7 @@ export DEBS = \ libbz2-dev\ libparse-recdescent-perl\ libhtml-defang-perl\ + libconfig-general-perl\ yaz export DEB_APACHE_MODS = \ diff --git a/Open-ILS/src/extras/install/Makefile.ubuntu-xenial b/Open-ILS/src/extras/install/Makefile.ubuntu-xenial index e8251b7cfd..9f67c14d19 100644 --- a/Open-ILS/src/extras/install/Makefile.ubuntu-xenial +++ b/Open-ILS/src/extras/install/Makefile.ubuntu-xenial @@ -74,6 +74,7 @@ export DEBS = \ libbz2-dev\ libparse-recdescent-perl\ libhtml-defang-perl\ + libconfig-general-perl\ yaz export DEB_APACHE_MODS = \ diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm index 14c797b12b..104cf71fc5 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm @@ -4288,6 +4288,8 @@ sub apply_new_li_ident_attr { $e->update_biblio_record_entry($bre) or return (undef, $e->die_event); + $U->create_events_for_hook('bre.edit', $bre, $e->requestor->ws_ou); + return ($source_attr); } diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm index 9f413b04c3..4cfcfbd573 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm @@ -172,6 +172,7 @@ sub biblio_record_replace_marc { $e, $recid, $newxml, $source, $fix_tcn, $oargs, $strip_grps); $e->commit unless $U->event_code($res); + $U->create_events_for_hook('bre.edit', $res, $e->requestor->ws_ou) unless $U->event_code($res);; return $res; } @@ -208,6 +209,7 @@ sub template_overlay_biblio_record_entry { my $success = $e->json_query( { from => [ 'vandelay.template_overlay_bib_record', $template, $rid ] } )->[0]->{'vandelay.template_overlay_bib_record'}; + $U->create_events_for_hook('bre.edit', $rec, $e->requestor->ws_ou); $conn->respond({ record => $rid, success => $success }); } @@ -284,6 +286,7 @@ sub template_overlay_container { if ($success eq 'f') { $num_failed++; } else { + $U->create_events_for_hook('bre.edit', $rec, $e->requestor->ws_ou); $num_succeeded++; } @@ -374,6 +377,7 @@ sub update_biblio_record_entry { return $e->die_event unless $e->allowed('UPDATE_RECORD'); $e->update_biblio_record_entry($record) or return $e->die_event; $e->commit; + $U->create_events_for_hook('bre.edit', $record, $e->requestor->ws_ou); return 1; } @@ -413,6 +417,7 @@ sub undelete_biblio_record_entry { $e->update_biblio_record_entry($record) or return $e->die_event; $e->commit; + $U->create_events_for_hook('bre.edit', $record, $e->requestor->ws_ou); return 1; } diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor/CallHTTP.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor/CallHTTP.pm new file mode 100644 index 0000000000..c79c374ff3 --- /dev/null +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor/CallHTTP.pm @@ -0,0 +1,149 @@ +package OpenILS::Application::Trigger::Reactor::CallHTTP; +use OpenILS::Application::Trigger::Reactor; +use base 'OpenILS::Application::Trigger::Reactor'; + +use OpenSRF::Utils::Logger qw/:logger/; +use OpenILS::Utils::CStoreEditor q/:funcs/; + +# use OpenSRF::Utils::SettingsClient; +use LWP::UserAgent; +use URI::Escape; +use Config::General qw(ParseConfig); + +use strict; +use warnings; + +sub ABOUT { + return < + Accept-Language en + + + + type bib + id [% target.id %] + + +content <run_TT($env) or return; + + my %request_config = ParseConfig( + -AutoTrue => 1, + -String => $HTTPcontent + ); + + return unless (keys %request_config); + + my $ua = LWP::UserAgent->new; + $ua->agent($request_config{agent} ? $request_config{agent} : 'EvergreenReactor/1.0'); + + my $url = $request_config{url} or return; + my $method = $request_config{method} or return; + return unless (grep { $_ eq $method } qw/post get put delete head/); + + my $user = $request_config{user}; + my $password = $request_config{password}; + my $realm = $request_config{realm}; + my $location = $request_config{location}; + + $ua->credentials($location, $realm, $user, $password) + if ($user and $password and $realm and $location); + + if ($request_config{Headers}) { + for my $h (keys %{$request_config{Headers}}) { + $ua->default_header( $h => $request_config{Headers}{$h} ); + } + } + + if ($request_config{Parameters}) { + $url .= '?'; + my $first = 1; + for my $p (keys %{$request_config{Parameters}}) { + my $pvalues = $request_config{Parameters}{$p}; + $pvalues = [$pvalues] if (!ref($pvalues)); + for my $pv (@$pvalues) { + $url .= "&" unless $first; + $first = 0; + $url .= "$p=".uri_escape($pv); + } + } + } + + my @params = ($url); + push( @params, Content => $request_config{content} ) + if (grep { $_ eq $method } qw/put post/); + + my $response = $ua->$method(@params); + my $output_field = $response->is_success ? 'async_output' : 'error_output'; + + my $e = new_editor(xact => 1); + my $eo = Fieldmapper::action_trigger::event_output->new; + $eo->is_error( $response->is_success ? 'f' : 't'); + $eo->data($response->as_string); + $eo = $e->create_action_trigger_event_output($eo) or return $e->die_event; + + my @eventids; + if (ref $$env{event} eq 'ARRAY') { + @eventids = map { $_->id} @{$$env{event}}; + } else { + @eventids = ($env->{event}->id); + } + + foreach (@eventids) { + my $event = $e->retrieve_action_trigger_event($_); + $event->$output_field($eo->id); + $e->update_action_trigger_event($event); + } + + $e->commit; + + return 1; +} + +1; + diff --git a/Open-ILS/src/sql/Pg/400.schema.action_trigger.sql b/Open-ILS/src/sql/Pg/400.schema.action_trigger.sql index 69b365d3f8..9388dbba07 100644 --- a/Open-ILS/src/sql/Pg/400.schema.action_trigger.sql +++ b/Open-ILS/src/sql/Pg/400.schema.action_trigger.sql @@ -57,6 +57,7 @@ INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('renewal','c INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('checkout.due.emergency_closing','aecc','Circulation due date was adjusted by the Emergency Closing handler'); INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('hold.shelf_expire.emergency_closing','aech','Hold shelf expire time was adjusted by the Emergency Closing handler'); INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('booking.due.emergency_closing','aecr','Booking reservation return date was adjusted by the Emergency Closing handler'); +INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('bre.edit','bre','A bib record was edited'); -- and much more, I'm sure diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index 822c6233cf..7100beac66 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -20585,3 +20585,7 @@ VALUES ( 'Grid Config: acq.search.invoices', 'cwst', 'label') ); + +INSERT INTO action_trigger.reactor (module, description) VALUES ( + 'CallHTTP', 'Push event information out to an external system via HTTP' +); diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.CallHTTP_at_reactor.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.CallHTTP_at_reactor.sql new file mode 100644 index 0000000000..e25e281352 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.CallHTTP_at_reactor.sql @@ -0,0 +1,14 @@ +BEGIN; + +SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version); + +INSERT INTO action_trigger.reactor (module, description) VALUES ( + 'CallHTTP', 'Push event information out to an external system via HTTP' +); + +INSERT INTO action_trigger.hook (key, core_type, description, passive) VALUES ( + 'bre.edit', 'bre', 'A bib record was edited', FALSE +); + +COMMIT; +