diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a0f29b --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Vim temp files. +.*.swp + +# Output files +api_adapter.cgi +get_aleph_info.csh +sql_lookup.cgi +sql_lookup.csh +sql_lookup.txt diff --git a/Aleph_API_Adapter_Users_Guide_v1.6.docx b/Aleph_API_Adapter_Users_Guide_v1.6.docx deleted file mode 100644 index 83d1197..0000000 Binary files a/Aleph_API_Adapter_Users_Guide_v1.6.docx and /dev/null differ diff --git a/README.md b/README.md index 12ad813..bf13fd1 100644 --- a/README.md +++ b/README.md @@ -1,350 +1,219 @@ -Aleph API Adapter User’s Guide -========================================================================================================================================================================================================================================================================= - -Version 1.6, December 2014 - -Overview -====================================================================================================== - -The Aleph API Adapter is a middleware script positioned between the -Aleph REST API and any external system that calls the REST API for -services. It has a small footprint, is easy to install, and is -unobtrusive in operation. Use of the adapter confers these benefits on -Aleph customers. - -1. Insulates an external system from a competing vendor’s product and - provides an avenue for problem circumvention that does not depend on - either Aleph or the vendor. - -2. Can minimize the latency of web traffic.  Some queries require - several separate operations against the Aleph API. If the external - system’s code runs directly against the Aleph API, every one of - those queries must make a round trip between the external server and - the Aleph server.  With the intermediate layer, one call from the - external server to the adapter can result in several calls to the - Aleph API, all of which are done on the Aleph server using - ‘localhost’.  None of the ‘localhost’ API calls goes out on the wire - and consequently are very fast. - -3. APIs change over time and across releases, contain bugs, and - sometimes are incomplete.  An intermediate layer can mask changes - unless or until they prove useful, and can compensate for missing - functionality. - -4. Simplifies access control.  Aleph controls access to APIs via IP - addresses.  Since the X-server is required in order to get Aleph ids - for use with the REST API, IP addresses for external servers must be - maintained in two places within Aleph: in - \$alephe\_tab/server\_ip\_allowed and in the Tomcat/JBoss - configuration. It is easier to maintain whitelists of approved IP - addresses in one place, the adapter, than it is in Aleph.  It also - gives the adapter more flexibility in serving other processes. - -5. Provides more flexibility for the external system.  If there is a - need for Aleph data to be filtered, or augmented from other local - systems, the adapter is a perfect place to do this without requiring - special programming on the external server. - -Design -==================================================================================================== - -The adapter was built to achieve these design goals. - -1. Easy to integrate into the Aleph server environment. - -2. Have a small footprint and be unobtrusive in its operation. - -3. Return results identical to those generated by the Aleph REST API - unless intentionally altered by the customer. - -4. Does not interfere in any way with the standard use of the Aleph - REST API through the Tomcat/JBOSS server. - -5. Consumes Aleph REST API URL syntax without modification. - -6. Function in a transparent pass-through mode for all REST API - services except for those intentionally modified by the host site. - -7. Can run on ports 80, 443, 8991, or any other port that may be in use - for the Aleph OPAC. - -Environment -=========== - -The adapter is intended to run from the cgi-bin subdirectory on Aleph’s -Apache server. During installation, it is activated by the completion of -two steps. - -1. Some Apache configuration directives must be activated in Apache to - trap REST URLs and route them to the adapter (see the Installation - section). If the .htaccess file is in use in the document root of - Aleph’s Apache server they can be included there. Otherwise they - will need to be included in the main Apache configuration file under - a stanza for the document root directory. - -2. The adapter will run on SSL (recommended), port 80, or other ports. - For example, some Aleph sites may use port 8991 for their OPAC - instead of port 80. The adapter should run on all such - configurations without modification.\ - \ - *Examples:\ - \ - *This URL calls the REST API directly using port 1891:\ - **http://\*:1891*/rest-dlf/patron/\/patronInformation\ - **\ - This URL calls the adapter using SSL:\ - **http***s***://\/rest-dlf/patron/\/patronInformation\ - \ - **This URL calls the adapter without SSL using port 80:\ - **http://\/rest-dlf/patron/\/patronInformation\ - \ - **This URL calls the adapter without SSL using port 8991:\ - **http://\*:8991*/rest-dlf/patron/\/patronInformation** - -When the adapter is implemented it does not foreclose the direct use of -the REST API on its specified port. The adapter does not interfere with -Tomcat/JBOSS operation in any way. - -Requirements -============ - -1. The adapter is written in Perl. Most Aleph servers have two - instances of Perl installed: one that is installed with the OS and - one that is installed as part of Aleph. The adapter defaults to - running under the standard Perl instance installed with the OS. It - is not dependent on the Aleph Perl instance. If the adapter is - intended to run under the Aleph-specific Perl installation, the - first lines of **api\_adapter.template, install\_adapter.pl**, and - **validate.pl** must be altered before the installation scripts are - run.\ - \ - The adapter requires that these four packages be present in the Perl - instance where it will run.\ - **HTTP::Request\ - LWP::UserAgent\ - Switch\ - POSIX\ - \ - **If the X-server is not licensed on the Aleph server, an SQL lookup - will be implemented. In this case, these two additional Perl - packages will be required:\ - **DBI\ - DBD::Oracle\ - ** - -2. JBOSS configuration\ - The adapter uses the server name ‘localhost’ when addressing Aleph’s - REST API. Consequently, IP address **127.0.0.1** must be included in - Aleph’s JBOSS configuration in - /exlibris/aleph/a\\_\/ng/aleph/home/system/thirdparty/openserver/server/default/deploy/jbossweb.sar/server.xml. - See Ex Libris manual *How to Configure the JBoss Server in Aleph*. - -3. Access to the X-server bor-by-key function is required for - conversion of aliases into aleph\_ids. Column 5 of - tab\_bor\_id.\ in the ADM library will need to be set to ‘Y’ - for each type of identifier that will be submitted from the remote - server.\ - \ - If the adapter is going to be run with id\_translation turned *off,* - the X-server whitelist in \$alephe\_tab/server\_ip\_allowed must - contain IP addresses for all remote servers that will need to look - up aleph\_ids. - -*\ -* -== - -Installation -============ - -1. Acquire the files from GitHub. - -2. Log into the Aleph system as user ‘aleph’. - -3. Change directory to the cgi-bin subdirectory of Aleph’s Apache - server, and copy the files to that directory. - -4. Add these directives to the .htaccess file in Apache’s DocumentRoot - directory e.g. - **/exlibris/aleph/u22\_1/alephe/apache/htdocs/.htaccess.** - - **\# Rewrite rules for Aleph API Adapter\ - RewriteEngine On** - - **RewriteBase /\ - RewriteCond %{REQUEST\_URI} \^/rest-dlf/\ - RewriteRule (rest-dlf/.\*) /cgi-bin/api\_adapter.cgi?parm1=\$1 - [E,L]\ - \ - **If the ‘**RewriteEngine’ and ‘RewriteBase’** directives already - exist in .htaccess, they do not need to be repeated.\ - \ - If the use of htdocs/.htaccess is not enabled on the Aleph system in - question, the rewrite rules can either be included at the - appropriate place in the Apache configuration, or the use of - .htaccess enabled by making a change in Apache’s httpd.conf file. - The default version of httpd.conf contains this stanza: - - \ - - Options FollowSymLinks MultiViews - - **AllowOverride None** - - Order Deny,Allow - - Allow from all - - \ - - Change ‘AllowOverride None’ to ‘AllowOverride All’. Apache should be - restarted after making this change. - -5. Run the installation script with this command:\ - **./install\_adapter.pl\ - **\ - The installation script will perform the following operations: - - a. Get the PWD environment variable and extract the version token - from the path. - - b. Prompt the installer for the institution’s name. This will be - used in the adapter’s response to an ‘ilsinstance’ call, the one - non-Aleph call that it accepts. Here is an example of the - structure returned by the ‘ilsinstance’ call, reporting the - institution’s name, the version of Aleph, and a few - site-specific Aleph variables:\ - \\ - \MIT\\ - \22.0.3\\ - \en\_US\\ - \Eastern Standard Time\\ - \EST\\ - \-5\\ - \USD\\ - \ - - c. Prompt the installer for the Tomcat/JBOSS port number. - - d. Prompt the installer for the status of the X-server. If the - X-server is not licensed for use on the Aleph server, an - alternative method of converting patron identifiers into Aleph - ids via SQL must be configured. - - e. If the X-server is not available, three other pieces of - information must be acquired. - - i. Prompt the installer for the Oracle user id and password of - the ADM library, which is usually \50. - - ii. Prompt for the z308 prefix of the identifiers that the - external system will submit for translation. This refers to - the first two characters in each patron record in the z308 - Oracle table. For example, ‘01’, or ’02’, or ‘03’ etc. - - f. Prompt the installer for an Aleph patron id to be used in - verifying the installation. - - g. Prompt the installer for the IP address of each remote server - that will call the adapter. - - h. Generate the ‘**get\_aleph\_info.csh**’ shell script from a - template, interpolating the version token as needed. - - i. Generate the ‘**api\_adapter.cgi**’ script from a template, - interpolating the server IP addresses into the whitelist and the - JBOSS port number into the appropriate variable. - - j. If the X-server is not available, generate the SQL lookup - scripts. - - i. Generate the ‘**sql\_lookup.csh**’ script from a template, - interpolating the Aleph version into file paths. - - ii. Generate the ‘**sql\_lookup.cgi**’ script from a template, - interpolating the Oracle user id, the Oracle password, and - the z308 prefix into the appropriate variables. - - k. Run **validate.pl** to test the installation. Validate.pl will - perform the following operations: - - i. Verify the presence of the required Perl packages and report - success or failure. - - ii. Using the Aleph id supplied by the installer, construct and - submit a URL to the X-server and report success or failure. - - iii. Using the Aleph id supplied by the installer, construct and - submit a URL to the REST API and report success or failure. - - iv. Verify the operation of the get\_aleph\_info.csh shell - script. - -6. If no errors are reported by the installation and validation - scripts, the installation is complete. The validation script - generates and displays a test URL. Test this URL from any server - whose IP address was specified during installation. It can be tested - from a browser if the browser’s IP address is part of the server - whitelist. - - - -Options -======= - -Id\_translation - -> This option is useful when the external system submits REST URLs that -> contain an alternate identifier instead of an Aleph id. With -> *id\_translation* set on (the default), the adapter extracts the -> incoming alternate identifier from the URL, calls the X-server to get -> the corresponding Aleph id, and substitutes the Aleph id for the -> alternate identifier in the call to the REST API. If this conversion -> of identifiers is not needed, *id\_translation* can be turned off. -> -> If a remote server needs to call the REST API with an alternate -> identifier, one of four scenarios must be followed. - -1. *The adapter is not installed.\ - *In this case, the remote server must first call the X-server’s - ‘bor-by-key’ function, passing the alternate identifier and - receiving the corresponding Aleph id. The Aleph id can then be - interpolated into subsequent calls to the REST API. - -2. *The adapter is installed, but *id\_translation* is turned off.\ - *This case requires the same process as case \#1. - -3. *The adapter is installed and *id\_translation* is turned on - (default)\ - *In this case the remote server calls the adapter with a REST URL - containing an alternate identifier. The adapter extracts the - alternate identifier, calls the X-server to retrieve the - corresponding Aleph id, replaces the alternate identifier in the URL - with the Aleph id, and sends the enhanced URL on to the REST API. - Since the X-server call in this case is done on the local server - without going out on the network it is very fast. - -4. *The adapter is installed and *id\_translation* is turned on - (default), but the X-server is not licensed for use on the Aleph - server.\ - *This case is the same as as case \#3 except that the adapter calls - SQL lookup scripts instead of the X-server for id translation. - -Under what circumstances should *id\_translation* be turned off? If the -remote server is populating all its REST URLs with Aleph ids, then the -translation step is wasted processing time. In that case, -id\_translation can be turned off with these actions: - -1. Make a backup copy of api\_adapter.cgi. - -2. Edit api\_adapter.cgi - -3. Find this text ‘my \$id\_translation = 1;’ and change the 1 to a - zero. - -4. Save the file. +Aleph API Adapter User’s Guide +============================== + +*Version 1.6.1, March 2015* + + +## Overview ## + +The Aleph API Adapter is a middleware script positioned between the Aleph REST API and any external system that calls the REST API for services. It has a small footprint, is easy to install, and is unobtrusive in operation. Use of the adapter confers these benefits on Aleph customers. + +1. Insulates an external system from a competing vendor’s product and provides an avenue for problem circumvention that does not depend on either Aleph or the vendor. + +2. Can minimize the latency of web traffic.  Some queries require several separate operations against the Aleph API. If the external system’s code runs directly against the Aleph API, every one of those queries must make a round trip between the external server and the Aleph server.  With the intermediate layer, one call from the external server to the adapter can result in several calls to the Aleph API, all of which are done on the Aleph server using ‘localhost’.  None of the ‘localhost’ API calls goes out on the wire and consequently are very fast. + +3. APIs change over time and across releases, contain bugs, and sometimes are incomplete.  An intermediate layer can mask changes unless or until they prove useful, and can compensate for missing functionality. + +4. Simplifies access control.  Aleph controls access to APIs via IP addresses.  Since the X-server is required in order to get Aleph ids for use with the REST API, IP addresses for external servers must be maintained in two places within Aleph: in `$alephe_tab/server_ip_allowed` and in the Tomcat/JBoss configuration. It is easier to maintain whitelists of approved IP addresses in one place, the adapter, than it is in Aleph.  It also gives the adapter more flexibility in serving other processes. + +5. Provides more flexibility for the external system.  If there is a need for Aleph data to be filtered, or augmented from other local systems, the adapter is a perfect place to do this without requiring special programming on the external server. + + +## Design ## + +The adapter was built to achieve these design goals. + +1. Easy to integrate into the Aleph server environment. + +2. Have a small footprint and be unobtrusive in its operation. + +3. Return results identical to those generated by the Aleph REST API unless intentionally altered by the customer. + +4. Does not interfere in any way with the standard use of the Aleph REST API through the Tomcat/JBoss server. + +5. Consumes Aleph REST API URL syntax without modification. + +6. Function in a transparent pass-through mode for all REST API services except for those intentionally modified by the host site. + +7. Can run on ports 80, 443, 8991, or any other port that may be in use for the Aleph OPAC. + + +## Environment ## + +The adapter is intended to run from the `cgi-bin` subdirectory on Aleph’s Apache server. During installation, it is activated by the completion of two steps. + +1. Some Apache configuration directives must be activated in Apache to trap REST URLs and route them to the adapter (see the *Installation section*). If the `.htaccess` file is in use in the document root of Aleph’s Apache server they can be included there. Otherwise they will need to be included in the main Apache configuration file under a stanza for the document root directory. + +2. The adapter will run on SSL (recommended), port 80, or other ports. For example, some Aleph sites may use port 8991 for their OPAC instead of port 80. The adapter should run on all such configurations without modification. + + ### Examples: ## + + - This URL calls the REST API directly using port 1891: + `http://`**`:1891`**`/rest-dlf/patron//patronInformation` + + - This URL calls the adapter using SSL: + `http`**`s`**`:///rest-dlf/patron//patronInformation` + + - This URL calls the adapter without SSL using port 80: + `http:///rest-dlf/patron//patronInformation` + + - This URL calls the adapter without SSL using port 8991: + `http://`**`:8991`**`/rest-dlf/patron//patronInformation` + +When the adapter is implemented it does not foreclose the direct use of the REST API on its specified port. The adapter does not interfere with Tomcat/JBoss operation in any way. + + +## Requirements ## + +1. The adapter is written in Perl. Most Aleph servers have two instances of Perl installed: one that is installed with the OS and one that is installed as part of Aleph. The adapter defaults to running under the standard Perl instance installed with the OS. It is not dependent on the Aleph Perl instance. If the adapter is intended to run under the Aleph-specific Perl installation, the first lines of `api_adapter.template`, `install_adapter.pl`, and `validate.pl` must be altered before the installation scripts are run. + + The adapter requires that these four packages be present in the Perl instance where it will run:
+ **DateTime**
+ **Fcntl**
+ **HTTP::Request**
+ **LWP::UserAgent**
+ **POSIX**
+ **Switch** + + If the X-server is not licensed on the Aleph server, an SQL lookup will be implemented. In this case, these two additional Perl packages will be required:
+ **DBI**
+ **DBD::Oracle** + +2. JBoss configuration + + The adapter uses the server name ‘localhost’ when addressing Aleph’s REST API. Consequently, IP address **127.0.0.1** must be included in Aleph’s JBoss configuration in `/exlibris/aleph/a_/ng/aleph/home/system/thirdparty/openserver/server/default/deploy/jbossweb.sar/server.xml`. + + See Ex Libris manual *How to Configure the JBoss Server in Aleph*. + +3. Access to the X-server `bor-by-key` function is required for conversion of aliases into aleph\_ids. Column 5 of `tab_bor_id.` in the ADM library will need to be set to `Y` for each type of identifier that will be submitted from the remote server. + + If the adapter is going to be run with id\_translation turned *off*, the X-server whitelist in `$alephe_tab/server_ip_allowed` must contain IP addresses for all remote servers that will need to look up aleph\_ids. + + +## Installation ## + +1. Acquire the files from GitHub. + +2. Log into the Aleph system as user ‘aleph’. + +3. Change directory to the `cgi-bin` subdirectory of Aleph’s Apache server, and copy the files to that directory. + +4. Add these directives to the `.htaccess` file in Apache’s DocumentRoot directory e.g. **`/exlibris/aleph/u22_1/alephe/apache/htdocs/.htaccess`**. + + ``` + # Rewrite rules for Aleph API Adapter + RewriteEngine On + + RewriteBase / + RewriteCond %{REQUEST_URI} ^/rest-dlf/ + RewriteRule (rest-dlf/.*) /cgi-bin/api_adapter.cgi?parm1=$1 [E,L] + ``` + + **If the ‘RewriteEngine’ and ‘RewriteBase’ directives already exist in .htaccess, they do not need to be repeated.** + + If the use of `htdocs/.htaccess` is not enabled on the Aleph system in question, the rewrite rules can either be included at the appropriate place in the Apache configuration, or the use of .htaccess enabled by making a change in Apache’s `httpd.conf` file. The default version of `httpd.conf` contains this stanza: + ``` + + Options FollowSymLinks MultiViews + AllowOverride None + Order Deny,Allow + Allow from all + + ``` + Change `AllowOverride None` to `AllowOverride All`. Apache should be restarted after making this change. + +5. Run the installation script with this command: **`./install_adapter.pl`** + + The installation script will perform the following operations: + + a. Get the ‘HOME’ environment variable and extract the version token from the path. + + b. Prompt the installer for the institution’s name. This will be used in the adapter’s response to an ‘ilsinstance’ call, the one non-Aleph call that it accepts. Here is an example of the structure returned by the ‘ilsinstance’ call, reporting the institution’s name, the version of Aleph, and a few site-specific Aleph variables: + ``` + + MIT + 22.0.3 + en_US + Eastern Standard Time + EST + -5 + USD + + ``` + + c. Prompt the installer for the Tomcat/JBoss port number. + + d. Prompt the installer for the status of the X-server. If the X-server is not licensed for use on the Aleph server, an alternative method of converting patron identifiers into Aleph ids via SQL must be configured. + + e. If the X-server is not available, three other pieces of information must be acquired. + + 1. Prompt the installer for the Oracle user id and password of the ADM library, which is usually ‘<xxx>50’. + + 2. Prompt for the ‘z308’ prefix of the identifiers that the external system will submit for translation. This refers to the first two characters in each patron record in the z308 Oracle table. For example, ‘01’, or ’02’, or ‘03’ etc. + + f. Prompt the installer for an Aleph patron id to be used in verifying the installation. + + g. Prompt the installer for the IP address of each remote server that will call the adapter. + + h. Generate the **`get_aleph_info.csh`** shell script from a template, interpolating the version token as needed. + + i. Generate the **`api_adapter.cgi`** script from a template, interpolating the server IP addresses into the whitelist and the JBoss port number into the appropriate variable. + + j. If the X-server is not available, generate the SQL lookup scripts. + + 1. Generate the **`sql_lookup.csh`** script from a template, interpolating the Aleph version into file paths. + + 2. Generate the **`sql_lookup.pl`** script from a template, interpolating the Oracle user id, the Oracle password, and the ‘z308’ prefix into the appropriate variables. + + k. Run **`validate.pl`** to test the installation. Validate.pl will perform the following operations: + + 1. Verify the presence of the required Perl packages and report success or failure. + + 2. Using the Aleph id supplied by the installer, construct and submit a URL to the X-server and report success or failure. + + 3. Using the Aleph id supplied by the installer, construct and submit a URL to the REST API and report success or failure. + + 4. Verify the operation of the `get_aleph_info.csh` shell script. + +6. If no errors are reported by the installation and validation scripts, the installation is complete. The validation script generates and displays a test URL. Test this URL from any server whose IP address was specified during installation. It can be tested from a browser if the browser’s IP address is part of the server whitelist. + + +## Options ## + +### Id\_translation ### + +This option is useful when the external system submits REST URLs that contain an alternate identifier instead of an Aleph id. With *id\_translation* set on (the default), the adapter extracts the incoming alternate identifier from the URL, calls the X-server to get the corresponding Aleph id, and substitutes the Aleph id for the alternate identifier in the call to the REST API. If this conversion of identifiers is not needed, *id\_translation* can be turned off. + +If a remote server needs to call the REST API with an alternate identifier, one of four scenarios must be followed. + +1. *The adapter is not installed.* + + In this case, the remote server must first call the X-server’s `bor-by-key` function, passing the alternate identifier and receiving the corresponding Aleph id. The Aleph id can then be interpolated into subsequent calls to the REST API. + +2. *The adapter is installed, but id\_translation is turned off.* + + This case requires the same process as case \#1. + +3. *The adapter is installed and id\_translation is turned on (default)* + + In this case the remote server calls the adapter with a REST URL containing an alternate identifier. The adapter extracts the alternate identifier, calls the X-server to retrieve the corresponding Aleph id, replaces the alternate identifier in the URL with the Aleph id, and sends the enhanced URL on to the REST API. Since the X-server call in this case is done on the local server without going out on the network it is very fast. + +4. *The adapter is installed and id\_translation is turned on (default), but the X-server is not licensed for use on the Aleph server.* + + This case is the same as as case \#3 except that the adapter calls SQL lookup scripts instead of the X-server for id translation. + +Under what circumstances should *id\_translation* be turned off? If the remote server is populating all its REST URLs with Aleph ids, then the translation step is wasted processing time. In that case, id\_translation can be turned off with these actions: + +1. Make a backup copy of `api_adapter.cgi`. + +2. Edit `api_adapter.cgi`. + +3. Find this text `my $id_translation = 1;` and change the 1 to a zero. + +4. Save the file. + + + + diff --git a/api_adapter.template b/api_adapter.template old mode 100755 new mode 100644 index ff78398..f860321 --- a/api_adapter.template +++ b/api_adapter.template @@ -1,276 +1,396 @@ -#!/usr/bin/perl +#!/usr/bin/perl #-------------------------------------------------------------- # 12-05-2014 Rich Wenger, MIT Libraries -# This script provides Aleph services to an external server. +# This script provides Aleph services to an external server. #-------------------------------------------------------------- use strict; use warnings; +use DateTime; use HTTP::Request; use LWP::UserAgent; -use Switch; use POSIX; -use Time::Local; +use Switch; my $rest_port = 'PORT'; my @whitelist = (WHITELIST); -#----------------------------------------------------------------- -# Only accept connections from authorized IP addresses. -#----------------------------------------------------------------- -if (!grep /$ENV{REMOTE_ADDR}/, @whitelist) { - print STDERR "*** $0: Unauthorized access attempt from $ENV{REMOTE_ADDR} ***\n"; - print "Content-type: text/html\n\n"; - print "Unathorized access"; - exit; - } + +#----------------------------------------------------------------------------------------- +# Uncomment the following setting to enable rewriting of any occurrence of +# string +# +# href="$int_protocol://$int_domain/$int_url_prefix +# +# (i.e. internal REST API URL) in the REST API response to string +# +# href="$ext_protocol://$ext_domain/$ext_url_prefix +# +# (i.e. external public REST API URL). +# +# This is useful if the public REST API URL differs from the default location +# and we want to provide correct links in our REST API responses. +#----------------------------------------------------------------------------------------- +my ($int_protocol, $int_domain, $int_url_prefix, + $ext_protocol, $ext_domain, $ext_url_prefix); +# ($int_protocol, $int_domain, $int_url_prefix, +# $ext_protocol, $ext_domain, $ext_url_prefix) +# = ('http', 'aleph.example.com', 'rest-dlf/', +# 'https', 'aleph.example.com', 'ebscoIntegrationApi/'); + + +# Based on comments of timezone name abbreviations at +# http://cpansearch.perl.org/src/DEXTER/POSIX-strftime-GNU-0.01/lib/POSIX/strftime/GNU/PP.pm +my $time_zone_short_name_deabbreviation = { + 'MIT' => 'Midway Islands Time', # -1100 + 'HAST' => 'Hawaii Standard Time', # -1000 + 'AKST' => 'Alaska Standard Time', # -0900 + 'PST' => 'Pacific Standard Time', # -0800 + 'AKDT' => 'Alaska Daylight Saving Time', # -0800 + 'PDT' => 'Pacific Daylight Saving Time', # -0700 + 'MST' => 'Mountain Standard Time', # -0700 + 'MDT' => 'Mountain Daylight Saving Time', # -0600 + 'CST' => 'Central Standard Time', # -0600 + 'EST' => 'Eastern Standard Time', # -0500 + 'CDT' => 'Central Daylight Saving Time', # -0500 + 'PRT' => 'Puerto Rico and US Virgin Islands Time', # -0400 + 'EDT' => 'Eastern Daylight Saving Time', # -0400 + 'CNT' => 'Canada Newfoundland Time', # -0330 + 'BET' => 'Brazil Eastern Time', # -0300 + 'AGT' => 'Argentina Standard Time', # -0300 + 'CAT' => 'Central African Time', # -0100 + 'GMT' => 'Universal Coordinated Time/Greenwich Mean Time', # +0000 + 'WET' => 'Western European Time', # +0000 + 'CET' => 'Central European Time', # +0100 + 'WEST' => 'Western European Summer Time', # +0100 + 'ART' => '(Arabic) Egypt Standard Time', # +0200 + 'CEST' => 'Central European Summer Time', # +0200 + 'EET' => 'Eastern European Time', # +0200 + 'EAT' => 'Eastern African Time', # +0300 + 'EEST' => 'Eastern European Summer Time', # +0300 + 'MET' => 'Middle East Time', # +0330 + 'NET' => 'Near East Time', # +0400 + 'PLT' => 'Pakistan Lahore Time', # +0500 + 'IST' => 'India Standard Time', # +0530 + 'BST' => 'Bangladesh Standard Time', # +0600 + 'ICT' => 'Indochina Time', # +0700 + 'AWST' => 'Australia Western Time', # +0800 + 'CTT' => 'China Taiwan Time', # +0800 + 'JST' => 'Japan Standard Time', # +0900 + 'ACST' => 'Australia Central Time', # +0930 + 'AEST' => 'Australia Eastern Time', # +1000 + 'SST' => 'Solomon Standard Time', # +1100 + 'NZST' => 'New Zealand Standard Time', # +1200 + 'NZST' => 'New Zealand Daylight Saving Time', # +1300 +}; #-------------------------------------------------------------------------------------------- # $debug and $parameter_trace are for diagnostic purposes and will normally be set to 0. # $id_translation will be set to 1 as a default. Setting it to 0 disables the translation -# of alternate identifiers to Aleph ids by the adapter. +# of alternate identifiers to Aleph ids by the adapter. #-------------------------------------------------------------------------------------------- -my $debug = 0; -my $parameter_trace = 0; -my $id_translation = 1; -my $sql_lookup = 0; +my $debug = 0; +my $parameter_trace = 0; +my $id_translation = 1; +my $sql_lookup = 0; + +#----------------------------------------------------------------- +# Only accept connections from authorized IP addresses. +#----------------------------------------------------------------- +if (!grep /^\Q$ENV{REMOTE_ADDR}\E$/, @whitelist) { + if ($debug) { + print STDERR "*** $0: Unauthorized access attempt from $ENV{REMOTE_ADDR} ***\n"; + } else { + print STDERR "*** Unauthorized access ***\n"; + } + print "Content-type: text/html\n\n"; + print "Unathorized access"; + exit; +} #------------------------------------------------------------------------ -# Local base URLs for the Aleph X-server and the RESTful API. +# Local base URLs for the Aleph X-server and the RESTful API. #------------------------------------------------------------------------ -my $x_base_url = 'http://localhost/X?'; -my $r_base_url = "http://localhost:$rest_port"; +my $x_base_url = 'http://localhost/X?'; +my $r_base_url = "http://localhost:$rest_port"; #------------------------------------- -# Headers and XML constants. +# Headers and XML constants. #------------------------------------- -my $xml_header = "Content-type: text/xml\n\n"; +my $xml_header = "Content-type: text/xml\n\n"; my $html_header = "Content-type: text/html\n\n"; -my $xml_prolog = ''; +my $xml_prolog = ''; -my $version_xml = join '', - '', - 'INSTNAME', - 'ALEPHVER', - 'en_US', - 'TIMEZONE', - 'TZCODE', - 'TZGMT', - 'CURRENCY', - ''; +my $version_xml = join '', + '', + 'INSTNAME', + 'ALEPHVER', + 'LOCALE', + 'TIMEZONE', + 'TZCODE', + 'TZGMT', + 'CURRENCY', + ''; my $printline = ''; my $putdata; my $postdata; #---------------------------------------------------- -# Valid parameters in Aleph RESTful URLs +# Valid parameters in Aleph RESTful URLs +# see https://developers.exlibrisgroup.com/aleph/apis/Aleph-RESTful-APIs #---------------------------------------------------- -my @allowed_groups = ('patron','ilsinstance','record'); -my @allowed_categories = ('patroninformation','circulationactions','record','patronstatus','items','holds'); -my @patinfo_functions = ('address','password'); -my @circ_functions = ('loans','requests','cash'); -my @patstatus_functions = ('blocks','registration'); -my @allowed_subfunctions = ('holds','photocopies','acquisitionrequests','ill','bookings'); +my @allowed_groups = ('patron','ilsinstance','record'); +#my @allowed_categories = ('patroninformation','circulationactions','acqRequest','record','patronstatus','items','filters','holdings'); +my @allowed_categories = ('patroninformation','circulationactions','record','patronstatus','items','holdings'); +#my @allowed_functions = ('address','password','loans','requests','cash','holds','acqRequest','shortLoan','ill','items','blocks','registration'); +my @allowed_functions = ('address','password','loans','requests','cash','blocks','registration'); +#my @allowed_subfunctions = ('holds','photocopies','acq','ill','bookings','hold','shortLoan','photo'); +my @allowed_subfunctions = ('holds','photocopies','acq','ill','bookings'); #-------------------------------- -# Valid HTTP methods +# Valid HTTP methods #-------------------------------- -my @allowed_methods = ('get','post','put','delete'); +my @allowed_methods = ('get','post','put','delete'); #---------------------------------------------------------------------------- -# Get the RESTful URL components. -# @parms will contain the RESTful nodes between slashes. -# @args will contain any key=value pairs from the end of the URI. +# Get the RESTful URL components. +# @parms will contain the RESTful nodes between slashes. +# @args will contain any key=value pairs from the end of the URI. #---------------------------------------------------------------------------- my @parms = split /\//, (split /\?parm1=/, lc $ENV{'REQUEST_URI'})[0]; splice @parms,0,2; +unless (@parms) { + print "$html_header invalid params"; + exit; +} my @args = split /\&/, (split /\?/, $parms[$#parms])[1]; if (grep /\?/, $parms[$#parms]) { - $parms[$#parms] =~ s/\?(.*)$//go; - } + $parms[$#parms] =~ s/\?(.*)$//go; +} + +my ($group, $object_id, $category, @other_params) = ''; + ($group, $object_id, $category, @other_params) = @parms; +my ($function_object, $function, $subfunction_object, $subfunction) = ''; +if ($category =~ /^(record|items|holdings)$/i) { + ($function_object, $function, $subfunction_object, $subfunction) = @other_params; +} elsif ($category =~ /^circulationactions$/i and $other_params[0] =~ /^(loans|cash)$/i) { + ($function, $subfunction_object, $subfunction) = @other_params; +} else { + ($function, $subfunction, $subfunction_object) = @other_params; +} -my ($group, $patron_id, $category, $function, $subfunction) = ''; -($group, $patron_id, $category, $function, $subfunction) = @parms; -if (!grep /$group/, @allowed_groups) { - print "$html_header invalid group $group"; - exit; - } -if (!grep /$category/, @allowed_categories) { - print "$html_header invalid category $category"; - exit; - } +if (!grep /^\Q$group\E$/i, @allowed_groups) { + print "$html_header invalid group '$group'"; + exit; +} +if (defined($category) and !grep /^\Q$category\E$/i, @allowed_categories) { + print "$html_header invalid category '$category'"; + exit; +} +if (defined($function) and !grep /^\Q$function\E$/i, @allowed_functions) { + print "$html_header invalid function '$function'"; + exit; +} +if (defined($subfunction) and !grep /^\Q$subfunction\E$/i, @allowed_subfunctions) { + print "$html_header invalid subfunction '$subfunction'"; + exit; +} #---------------------------------------------------------------------------------------- -# $method will contain one of the HTTP commands: GET, POST, PUT, DELETE, etc. -# They are stored here in lower case for later use as method calls to LWP. +# $method will contain one of the HTTP commands: GET, POST, PUT, DELETE, etc. +# They are stored here in lower case for later use as method calls to LWP. #---------------------------------------------------------------------------------------- my $method = lc $ENV{'REQUEST_METHOD'}; +if (!grep /^\Q$method\E$/i, @allowed_methods) { + print "$html_header invalid method '$method'"; + exit; +} #------------------------------------------------------------------------------ -# This paragraph is for diagnostic purposes only. It writes parameters -# and arguments to the Apache log (STDERR) and exits. +# This paragraph is for diagnostic purposes only. It writes parameters +# and arguments to the Apache log (STDERR) and exits. #------------------------------------------------------------------------------ if ($parameter_trace) { - print "$html_header"; - foreach my $x (@parms) { print "parm: $x
"; } - if (@args) { - foreach my $x (@args) { print "args: $x
"; } - } - if ($debug) { - my $printline = join '', - "*** Group: $group ***\n", - "*** Patron id: $patron_id ***\n", - "*** Category: $category ***\n", - "*** Function: $function ***\n", - "*** Subfunction: $subfunction ***\n"; - print STDERR $printline; - } - exit; - } + print "$html_header"; + foreach my $x (@parms) { print "parm: $x
"; } + foreach my $x (@args) { print "args: $x
"; } + if ($debug) { + my $printline = join '', + "*** Group: $group ***\n", + "*** Object Id: $object_id ***\n", + "*** Category: $category ***\n", + "*** Function: $function ***\n", + "*** Subfunction: $subfunction ***\n"; + print STDERR $printline; + } + exit; +} #---------------------------------------------------------------------------- -# This section handles the request for Aleph version information. -# The Aleph REST API does not support this operation. +# This section handles the request for Aleph version information. +# The Aleph REST API does not support this operation. #---------------------------------------------------------------------------- if ($group eq 'ilsinstance') { - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - my $timezone = $isdst ? 'Eastern Daylight Time' : 'Eastern Standard Time'; - my $tzcode = $isdst ? 'EDT' : 'EST'; + my $dt = DateTime->now( time_zone => 'local' ); + my $gmt_offset_in_hours = $dt->offset() / 3600; + my $tzcode = $dt->time_zone_short_name(); + my $timezone = $dt->time_zone_long_name(); - my @aleph_info = `./get_aleph_info.csh`; - my $version = (split ',', $aleph_info[0])[2]; - my $aleph_version = (split ' ', $version)[1]; - my $currency = $aleph_info[3]; - chomp $currency; + # For some timezones, time_zone_long_name() returns more specific place name + # than simple ‘deabbreviation’ of the time zone code + # (e.g. ‘CET’ -> ‘Europe/Prague’ instead of ‘CET’ -> ‘Central Standard Time’). + # On the next line we are trying to determine the standard time zone name + # and use it if possible. + $timezone = $time_zone_short_name_deabbreviation->{$tzcode} if (exists($time_zone_short_name_deabbreviation->{$tzcode})); - my @t = localtime(time); - my $gmt_offset_in_hours = (timegm(@t) - timelocal(@t)) / 3600; + my @aleph_info = `./get_aleph_info.csh`; + my $version = (split ',', $aleph_info[0])[2]; + my $aleph_version = (split ' ', $version)[1]; + my $currency = $aleph_info[scalar(@aleph_info)-1]; # Currency is the last line of the Aleph info list. + chomp $currency; - my $version_string = $version_xml; - $version_string =~ s/ALEPHVER/$aleph_version/; - $version_string =~ s/TIMEZONE/$timezone/; - $version_string =~ s/TZCODE/$tzcode/; - $version_string =~ s/TZGMT/$gmt_offset_in_hours/; - $version_string =~ s/CURRENCY/$currency/; + my $version_string = $version_xml; + $version_string =~ s/ALEPHVER/$aleph_version/; + $version_string =~ s/TIMEZONE/$timezone/; + $version_string =~ s/TZCODE/$tzcode/; + $version_string =~ s/TZGMT/$gmt_offset_in_hours/; + $version_string =~ s/CURRENCY/$currency/; - $printline = join '', $xml_prolog, $version_string; - } + $printline = join '', $xml_prolog, $version_string; +} else { + #---------------------------------------------------------------------- + # Instantiate a user agent for use in calling the REST API. + #---------------------------------------------------------------------- + my $ua = LWP::UserAgent->new; -else { - #---------------------------------------------------------------------- - # Instantiate a user agent for use in calling the REST API. - #---------------------------------------------------------------------- - my $ua = LWP::UserAgent->new; + my $request_uri = $ENV{'REQUEST_URI'}; + #---------------------------------------------------------------------- + # Rewrite URL prefix for request. + #---------------------------------------------------------------------- + if (defined($request_uri) + and defined($int_url_prefix) and defined($ext_url_prefix)) { + $request_uri =~ s/^(\/)\Q$ext_url_prefix\E/$1$int_url_prefix/g; + } + my $response = ''; + my $aleph_id = ''; + if ($group eq 'patron' && $id_translation) { + if (!$sql_lookup) { + #--------------------------------------------------------------------- + # Incoming identifer requires translation. Since $sql_lookup + # is not set, convert it to an Aleph id via bor-by-key + # x-server function, + #--------------------------------------------------------------------- + my $info_prefix = "op=bor-by-key&bor_id=$object_id"; + my $rest_url = join '', $x_base_url, $info_prefix; + print STDERR "*** Bor-by-key URL: $rest_url ***\n" if $debug; + $response = $ua->get($rest_url); + $aleph_id = &extract_alephid($response); + print STDERR "*** Aleph id: $aleph_id ***\n" if $debug; + print STDERR "*** Patron id: $object_id ***\n" if $debug; + print STDERR "*** request_uri before: $request_uri ***\n" if $debug; + $request_uri =~ s/(\/patron\/)\Q$object_id\E/$1$aleph_id/ig; + print STDERR "*** request_uri after: $request_uri ***\n" if $debug; + } else { + #--------------------------------------------------------------------- + # Incoming identifer requires translation. Since $sql_lookup + # is on, convert it to an Aleph id via SQL lookup. + #--------------------------------------------------------------------- + $aleph_id = `./sql_lookup.csh '$object_id'`; + print STDERR "*** Aleph id from SQL: $aleph_id ***\n" if $debug; + $request_uri =~ s/(\/patron\/)\Q$object_id\E/$1$aleph_id/ig; + } + } - my $request_uri = $ENV{'REQUEST_URI'}; - my $response = ''; - my $aleph_id = ''; - if ($group eq 'patron' && $id_translation) { - if (!$sql_lookup) { - #--------------------------------------------------------------------- - # Incoming identifer requires translation. Since $sql_lookup - # is not set, convert it to an Aleph id via bor-by-key - # x-server function, - #--------------------------------------------------------------------- - my $info_prefix = "op=bor-by-key&bor_id=$patron_id"; - my $rest_url = join '', $x_base_url, $info_prefix; - print STDERR "*** Bor-by-key URL: $rest_url ***\n" if $debug; - $response = $ua->get($rest_url); - $aleph_id = &extract_alephid($response); - print STDERR "*** Aleph id: $aleph_id ***\n" if $debug; - print STDERR "*** Patron id: $patron_id ***\n" if $debug; - print STDERR "*** request_uri before: $request_uri ***\n" if $debug; - $request_uri =~ s/$patron_id/$aleph_id/ig; - print STDERR "*** request_uri after: $request_uri ***\n" if $debug; - } - else { - #--------------------------------------------------------------------- - # Incoming identifer requires translation. Since $sql_lookup - # is on, convert it to an Aleph id via SQL lookup. - #--------------------------------------------------------------------- - $aleph_id = `./sql_lookup.csh $patron_id`; - print STDERR "*** Aleph id from SQL: $aleph_id ***\n" if $debug; - $request_uri =~ s/$patron_id/$aleph_id/ig; - } - } + if (grep /^\Q$method\E$/i, @allowed_methods) { + #----------------------------------- + # Optional local programming can be inserted here by uncommenting the + # switch structure below + #----------------------------------- + # switch (lc($category)) { + # case ('patroninformation') { + # # local code here + # } + # case ('patronstatus') { + # # local code here + # } + # case ('circulationactions') { + # # local code here + # } + # case ('record') { + # # local code here + # } + # case ('items') { + # # local code here + # } + # } + #----------------------------------- + # Default passthrough. + #----------------------------------- + my $rest_url = join '', $r_base_url, $request_uri; + print STDERR "*** $category: $rest_url ***\n" if $debug; + print STDERR "*** Method: $method ***\n" if $debug; + my $request; + switch ($method) { + case ('get') { + $request = HTTP::Request->new(GET => $rest_url); + } + case ('post') { + read(STDIN, $putdata, $ENV{'CONTENT_LENGTH'}); + my $h = HTTP::Headers->new(Content_Type => 'text/xml'); + $request = HTTP::Request->new('POST', $rest_url, $h, $putdata); + } + case ('put') { + read(STDIN, $putdata, $ENV{'CONTENT_LENGTH'}); + my $h = HTTP::Headers->new(Content_Type => 'text/xml'); + $request = HTTP::Request->new('PUT', $rest_url, $h, $putdata); + } + case ('delete') { + $request = HTTP::Request->new(DELETE => $rest_url); + } + } + $response = $ua->request($request); + $printline = $response->content; + #------------------------------------------------------------ + # Remove the port number from any URLs in the XML. + #------------------------------------------------------------ + $printline =~ s/localhost:\Q$rest_port\E/$ENV{'HTTP_HOST'}/go; + } else { + #------------------------------------------------------------------ + # HTTP method is not supported. Return failure message + #------------------------------------------------------------------ + $printline = join '', $xml_prolog, "HTTP command $method is restricted or invalid"; + } +} - if (grep /$method/, @allowed_methods) { - #----------------------------------- - # Optional local programming can be inserted here by uncommenting the - # switch structure below - #----------------------------------- - #switch ($category) { - # case ('patroninformation') { - # # local code here - # } - # case ('patronstatus') { - # # local code here - # } - # case ('circulationactions') { - # # local code here - # } - # case ('record') { - # # local code here - # } - # case ('items') { - # # local code here - # } - # } - #----------------------------------- - # Default passthrough. - #----------------------------------- - my $rest_url = join '', $r_base_url, $request_uri; - print STDERR "*** $category: $rest_url ***\n" if $debug; - print STDERR "*** Method: $method ***\n" if $debug; - my $request; - switch ($method) { - case ('get') { - $request = HTTP::Request->new(GET => $rest_url); - } - case ('post') { - read(STDIN, $putdata, $ENV{'CONTENT_LENGTH'}); - my $h = HTTP::Headers->new(Content_Type => 'text/xml'); - $request = HTTP::Request->new('POST', $rest_url, $h, $putdata); - } - case ('put') { - read(STDIN, $putdata, $ENV{'CONTENT_LENGTH'}); - my $h = HTTP::Headers->new(Content_Type => 'text/xml'); - $request = HTTP::Request->new('PUT', $rest_url, $h, $putdata); - } - case ('delete') { - $request = HTTP::Request->new(DELETE => $rest_url); - } - } - $response = $ua->request($request); - $printline = $response->content; - #------------------------------------------------------------ - # Remove the port number from any URLs in the XML. - #------------------------------------------------------------ - $printline =~ s/localhost:$rest_port/$ENV{'HTTP_HOST'}/go; - } - else { - #------------------------------------------------------------------ - # HTTP method is not supported. Return failure message - #------------------------------------------------------------------ - $printline = join '', $xml_prolog, "HTTP command $method is restricted or invalid"; - } - } +#----------------------------------------------------------------------------------------- +# Rewrite URL prefix in the response. +#----------------------------------------------------------------------------------------- +if (defined($printline) + and defined($int_protocol) and defined($int_domain) and defined($int_url_prefix) + and defined($ext_protocol) and defined($ext_domain) and defined($ext_url_prefix)) { + $printline =~ s/(href=['"])\Q$int_protocol\E(:\/\/)\Q$int_domain\E(\/)\Q$int_url_prefix\E/$1$ext_protocol$2$ext_domain$3$ext_url_prefix/g; +} #----------------------------------------------------------------------------------------- -# Return the content to the caller. -# The following 'if' statement is required to ameliorate the Aleph REST API's -# inexplicable practice of returning HTML in certain error conditions. +# Return the content to the caller. +# The following 'if' statement is required to ameliorate the Aleph REST API's +# inexplicable practice of returning HTML in certain error conditions. #----------------------------------------------------------------------------------------- print STDERR "*** printline: $printline ***\n" if $debug; -if (grep //, $printline) { print "$html_header" } -else { print "$xml_header" } +if (grep //, $printline) { + print "$html_header" +} else { + print "$xml_header" +} print $printline; exit; #------------------------- subroutines -------------------------- sub extract_alephid { - my $xml_ref = pop; - my @temp = split '<\/internal\-id>', (split '', $xml_ref->content)[1]; - return $temp[0]; - } + my $xml_ref = pop; + my @temp = split '<\/internal\-id>', (split '', $xml_ref->content)[1]; + return $temp[0]; +} + +# vim:textwidth=80:expandtab:tabstop=4:shiftwidth=4:fileencodings=utf8:spelllang=en diff --git a/get_aleph_info.template b/get_aleph_info.template index 5e5d056..446b88d 100644 --- a/get_aleph_info.template +++ b/get_aleph_info.template @@ -2,3 +2,5 @@ source /exlibris/aleph/VER/alephm/.cshrc >/dev/null ver echo $local_currency + +# vim:textwidth=80:expandtab:tabstop=4:shiftwidth=4:fileencodings=utf8:spelllang=en diff --git a/install_adapter.pl b/install_adapter.pl index 6ca1801..da01655 100755 --- a/install_adapter.pl +++ b/install_adapter.pl @@ -3,37 +3,48 @@ use strict; use warnings; -my $input_file1 = 'get_aleph_info.template'; -my $output_file1 = 'get_aleph_info.csh'; +use Fcntl qw( :mode ); -my $input_file2 = 'api_adapter.template'; -my $output_file2 = 'api_adapter.cgi'; +my $get_aleph_info_template_file = 'get_aleph_info.template'; +my $get_aleph_info_file = 'get_aleph_info.csh'; -my $input_file3 = 'sql_lookup.csh.template'; -my $output_file3 = 'sql_lookup.csh'; +my $api_adapter_template_file = 'api_adapter.template'; +my $api_adapter_file = 'api_adapter.cgi'; -my $input_file4 = 'sql_lookup.cgi.template'; -my $output_file4 = 'sql_lookup.cgi'; +my $sql_lookup_template_file = 'sql_lookup.csh.template'; +my $sql_lookup_file = 'sql_lookup.csh'; + +my $sql_lookup_pl_template_file = 'sql_lookup.pl.template'; +my $sql_lookup_pl_file = 'sql_lookup.pl'; #------------------------------------------- # Extract the version token from the path #------------------------------------------- -my $string = $ENV{PWD}; -my $ver = substr($string,16,5); -$ver =~ s/u/a/i; +my $current_user_home_dir = $ENV{HOME}; +my $ver; +if ($current_user_home_dir =~ /[au]([^\/]+?)\/alephm$/) { + $ver = "a$1"; +} else { + die "Unable to extract Aleph version from the current user \$HOME path\n"; +} #----------------------------------------------------- -# Prompt the installer for the institution's name. +# Prompt the installer for the institution's name. #----------------------------------------------------- my $instname = display(\"\nPlease enter the name of your institution (q=quit): "); +#----------------------------------------------------- +# Prompt the installer for the locale. +#----------------------------------------------------- +my $locale = display(\"\nPlease enter the locale (e.g. 'en_US') of your system installation (q=quit): "); + #----------------------------------------------------------- -# Prompt the installer for Aleph's REST API port number. +# Prompt the installer for Aleph's REST API port number. #----------------------------------------------------------- my $jboss_port = display(\"\nPlease enter the JBOSS port number for Aleph's REST API (q=quit): "); #------------------------------------------------------------------- -# Prompt the installer for the license status of Aleph's X-server. +# Prompt the installer for the license status of Aleph's X-server. #------------------------------------------------------------------- my $xsl = display(\"\nIs the X-server licensed for use on this server ? "); if (grep /y/i, $xsl) {$xsl = 1} else {$xsl = 0} @@ -41,130 +52,140 @@ #---------------------------------------------------------- # Store this indicator for later reading by validate.pl. #---------------------------------------------------------- -open(FH1,">sql_lookup.txt"); -print FH1 "$xsl\n"; -close(FH1); +open(OUTPUT,">sql_lookup.txt"); +print OUTPUT "$xsl\n"; +close(OUTPUT); +my $db_schema; my $db_user; my $db_password; my $z308_prefix; if (!$xsl) { - #------------------------------------------------------------------- - # Prompt the installer for the Oracle user id of the ADM library, - # usually 50, and that user's Oracle password. - #------------------------------------------------------------------- - $db_user = display(\"\nPlease enter the Oracle user id for the ADM library (usually 50): "); + #------------------------------------------------------------------- + # Prompt the installer for the Oracle user id of the ADM library, + # usually 50, and that user's Oracle password. + #------------------------------------------------------------------- + $db_schema = display(\"\nPlease enter the Oracle schema id for the USR library (usually 00): "); + + $db_user = display(\"\nPlease enter the Oracle user id with the right reading $db_schema.Z308 table: "); - $db_password = display(\"\nPlease enter the Oracle password for user id $db_user: "); + $db_password = display(\"\nPlease enter the Oracle password for user id $db_user: "); - $z308_prefix = display(\"\nPlease enter the two-number 'type' prefix from the Z308 Oracle table that corresponds with the identifiers that will be submitted for lookup: "); - } + $z308_prefix = display(\"\nPlease enter the two-number 'type' prefix from the $db_schema.Z308 Oracle table that corresponds with the identifiers that will be submitted for lookup: "); +} #------------------------------------------------------------- -# Prompt the installer for a patron's Aleph id to be used -# in testing access to the X-server and REST API. +# Prompt the installer for a patron's Aleph id to be used +# in testing access to the X-server and REST API. #------------------------------------------------------------- my $aleph_id; if ($xsl) { - $aleph_id = display(\"\nPlease enter a patron's Aleph id that can be used to test access to the X-server and the REST API: "); - } -else { - $aleph_id = display(\"\nPlease enter a patron's Aleph id that can be used to test access to the REST API: "); - } + $aleph_id = display(\"\nPlease enter a patron's Aleph id that can be used to test access to the X-server and the REST API: "); +} else { + $aleph_id = display(\"\nPlease enter a patron's Aleph id that can be used to test access to the REST API: "); +} #------------------------------------------------------------------- # Prompt the installer for the IP addresses of the remote servers # that will call the adapter. These IP addresses will be inserted -# into the adapter's whitelist. +# into the adapter's whitelist. #------------------------------------------------------------------- my $ip_string = display(\"\nPlease enter the IP addresses of the remote servers that will call the adapter. Separate multiple addresses with commas e.g. 10.10.10.10,11.11.11.11 etc.\n"); my @ip_addresses = split /,/, $ip_string; foreach (@ip_addresses) { - $_ = join '', "'", $_, "'" - } + $_ = join '', "'", $_, "'" +} $ip_string = join ',', @ip_addresses; #---------------------------------------------------------------------- # Generate the get_aleph_info.csh script from a template. # Substitute the version token into the path of the 'source' command. #---------------------------------------------------------------------- -open(FH1,"<$input_file1") or die "Unable to open input file $input_file1\n"; -open(FH2,">$output_file1") or die "Unable to open output file $output_file1\n"; -while () { - if (grep /source/, $_) { - $_ =~ s/VER/$ver/g; - } - print FH2; - } -`chmod +x $output_file1`; -close(FH1); -close(FH2); +open(TEMPLATE,"<$get_aleph_info_template_file") or die "Unable to open input file $get_aleph_info_template_file\n"; +open(OUTPUT,">$get_aleph_info_file") or die "Unable to open output file $get_aleph_info_file\n"; +while (