1 = oai-openils is an openSRF service
3 This module is an optional service that exposes your catalog through the [OAI2 protocol](http://www.openarchives.org/OAI/openarchivesprotocol.html).
5 == 1. Intended behaviour
8 There are two: one for bibliographic records and one for authority records:
10 http://your-domain/opac/extras/oai/authority
11 http://your-domain/opac/extras/oai/biblio
13 === 1.2 Setspec are not implemented
15 This is a work in progress and not enabled. The aim is to have the owning library determine the set hierarchy. The Concerto
16 test database for example has a record with tcn #1. This record is so popular it has copies attached to library units
17 "Example Branch 1", "Example Branch 2", "Example Branch 3", "Example Bookmobile 1" which is a child of Branch 3 and
18 "Example Branch 4". This entire kinship is expressed as sets like so:
23 <setSpec>CONS</setSpec>
24 <setSpec>CONS:SYS1</setSpec>
25 <setSpec>CONS:SYS2</setSpec>
26 <setSpec>CONS:SYS1:BR1</setSpec>
27 <setSpec>CONS:SYS1:BR2</setSpec>
28 <setSpec>CONS:SYS2:BR3</setSpec>
29 <setSpec>CONS:SYS2:BR4</setSpec>
30 <setSpec>CONS:SYS2:BR3:BM1</setSpec>
33 Likewise the setSpecs of authority records are derived from their browse axis ( Title, Author, Subject and Topic ).
35 === 1.3 OAI2 datestamp
37 The edit date of the bibliographic and authority record is used as datestamp. If you want the date for editorial updates
38 of bibliographic assets ( copies, call numbers ) reflected in the datestamp, then add the triggers shown below.
40 === 1.4 Bibliographic mapping of assets to 852 subfields
42 Certain attributes asset are placed into 852 subfields so:
44 | subfield code | asset resource |
53 Thus the Concerto with tcn #1 will have it's 852 subfields expressed as:
55 <marc:datafield ind1="4" ind2=" " tag="852">
56 <marc:subfield code="a">Stacks</marc:subfield>
57 <marc:subfield code="b">BR4</marc:subfield>
58 <marc:subfield code="c">ML 60 R100</marc:subfield>
59 <marc:subfield code="d">BR4</marc:subfield>
60 <marc:subfield code="g">CONC70000435</marc:subfield>
61 <marc:subfield code="n">Checked out</marc:subfield>
64 This mapping can be customized and extended with static subfields:
66 <marc:subfield code="q">A constant value</marc:subfield>
69 === 1.5 Default configuration
71 All default configuration is commented in the open-ils.oai app_settings element. See below for details on how to
72 override defaults by removing the comments and substitute the values.
78 Lookup the Perl handler and the associated openils module:
80 - [Open-ILS/src/perlmods/lib/OpenILS/WWW/OAI.pm](Open-ILS/src/perlmods/lib/OpenILS/WWW/OAI.pm)
81 - [Open-ILS/src/perlmods/lib/OpenILS/Application/OAI.pm](Open-ILS/src/perlmods/lib/OpenILS/Application/OAI.pm)
83 Place them in your codebase next to the other openils modules and let them thus become part of the build:
85 Open-ILS/src/perlmods/lib/OpenILS/Application/OAI.pm
86 Open-ILS/src/perlmods/lib/OpenILS/WWW/OAI.pm
88 or copy the files (owned by the opensrf user) on your servers that host the openils services in the Perl library path:
90 /the perl library path/OpenILS/Application/OAI.pm
91 /the perl library path/OpenILS/WWW/OAI.pm
93 === 2.2 Declare the perl handler
95 Declare the Perl handler in the Apache eg_startup file:
98 use OpenILS::WWW::OAI qw( <openils sysdir>conf/opensrf_core.xml );
101 And reference it in the Apache eg_vhost.conf file, apache 2.2:
103 <Location /opac/extras/oai>
104 SetHandler perl-script
105 PerlHandler OpenILS::WWW::OAI
113 <Location /opac/extras/oai>
114 SetHandler perl-script
115 PerlHandler OpenILS::WWW::OAI
121 In the eg.conf file under 'PerlRequire /etc/apache2/eg_startup' add:
123 PerlChildInitHandler OpenILS::WWW::OAI::child_init
127 === 2.3 The database and fieldmapper
131 The service requires a view and stored procedures: Open-ILS/src/sql/Pg/oai.sql
133 Add the oai section to the database:
135 -- VIEWS for the oai service
139 -- The view presents a lean table with unique bre.tc-numbers for oai paging;
140 CREATE VIEW oai.biblio AS
143 bre.edit_date AS datestamp,
144 bre.deleted AS deleted
146 biblio.record_entry bre
150 -- The view presents a lean table with unique are.tc-numbers for oai paging;
151 CREATE VIEW oai.authority AS
154 are.edit_date AS datestamp,
155 are.deleted AS deleted
157 authority.record_entry AS are
162 ==== 2.3.2 Optional, setting the datestamp
164 If you want the OAI2 datestamp to reflect changes in assets as well, add the following triggers
167 -- If an edit date changes in the asset.call_number or asset.copy and you want this to persist to an OAI2 datestamp,
168 -- then add these stored procedures and triggers:
169 CREATE OR REPLACE FUNCTION oai.datestamp(rid BIGINT)
172 UPDATE biblio.record_entry AS bre
173 SET edit_date = now()
178 CREATE OR REPLACE FUNCTION oai.call_number_datestamp()
179 RETURNS TRIGGER AS $$
183 PERFORM oai.datestamp(OLD.record);
187 PERFORM oai.datestamp(NEW.record);
193 CREATE OR REPLACE FUNCTION oai.copy_datestamp()
194 RETURNS TRIGGER AS $$
198 PERFORM oai.datestamp((SELECT acn.record FROM asset.call_number as acn WHERE acn.id = OLD.call_number));
202 PERFORM oai.datestamp((SELECT acn.record FROM asset.call_number as acn WHERE acn.id = NEW.call_number));
208 CREATE TRIGGER call_number_datestamp AFTER INSERT OR UPDATE OR DELETE ON asset.call_number FOR EACH ROW EXECUTE PROCEDURE oai.call_number_datestamp();
209 CREATE TRIGGER copy_datestamp AFTER INSERT OR UPDATE OR DELETE ON asset.copy FOR EACH ROW EXECUTE PROCEDURE oai.copy_datestamp();
212 ==== 2.3.3 The fieldmapper
214 Proceed by declaring the views in the fm_IDL.xml file so, as the example shows here [Open-ILS/examples/fm_ILD.xml](Open-ILS/examples/fm_IDL.xml):
217 <class id="oai_biblio" controller="open-ils.cstore" oils_obj:fieldmapper="oai::biblio"
218 oils_persist:readonly="true" reporter:core="false" reporter:label="OAI2 record list"
219 oils_persist:tablename="oai.biblio">
221 <field reporter:label="TCN Value\OAI identifier postfix" name="tcn" reporter:datatype="number"/>
222 <field reporter:label="Last edit date\OAI datestamp" name="datestamp" reporter:datatype="timestamp"/>
223 <field reporter:label="Is Deleted?" name="deleted" reporter:datatype="bool"/>
224 <field reporter:label="Setspec" name="set_spec" oils_persist:virtual="true"/>
227 <class id="oai_authority" controller="open-ils.cstore" oils_obj:fieldmapper="oai::authority"
228 oils_persist:readonly="true" reporter:core="false" reporter:label="OAI2 record list"
229 oils_persist:tablename="oai.authority">
231 <field reporter:label="TCN Value\OAI identifier postfix" name="tcn" reporter:datatype="number"/>
232 <field reporter:label="Last edit date\OAI datestamp" name="datestamp" reporter:datatype="timestamp"/>
233 <field reporter:label="Is Deleted?" name="deleted" reporter:datatype="bool"/>
234 <field reporter:label="Setspec" name="set_spec" oils_persist:virtual="true"/>
239 === 2.4 The xslt stylesheets
241 Lookup the two documents here:
243 - [Open-ILS/xsl/OAI2_OAIDC.xsl](Open-ILS/xsl/OAI2_OAIDC.xsl)
244 - [Open-ILS/xsl/OAI2_MARC21slim.xsl](Open-ILS/xsl/OAI2_MARC21slim.xsl)
246 Place the stylesheets in your codebase next to the other xsl documents and let them thus become part of the build.
247 Or install them on your servers that host the openils services:
249 /<openils sysdir>/var/xsl/OAI2_OAIDC.xsl
250 /<openils sysdir>/var/xsl/OAI2_MARC21slim.xsl
253 The openils-oai service depends on a running openils-supercat service.
254 And the OAI2_OAIDC.xsl document uses the file [MARC21slim2OAIDC.xsl](Open-ILS/xsl/MARC21slim2OAIDC.xsl).
255 The service and stylesheet are part of the out-of-the-box Evergreen distributions.
257 But do install the ['HTTP::OAI' perl library from a CPAN repository](http://search.cpan.org/dist/HTTP-OAI/):
264 === 3.1 Declare the service
266 Add the openils-oai service to your /<openils sysdir>/conf/opensrf.xml file.
270 <keepalive>5</keepalive>
271 <stateless>1</stateless>
272 <language>perl</language>
273 <implementation>OpenILS::Application::OAI</implementation>
274 <max_requests>199</max_requests>
276 <unix_sock>open-ils.oai_unix.sock</unix_sock>
277 <unix_pid>open-ils.oai_unix.pid</unix_pid>
278 <max_requests>1000</max_requests>
279 <unix_log>open-ils.oai_unix.log</unix_log>
280 <min_children>1</min_children>
281 <max_children>5</max_children>
282 <min_spare_children>1</min_spare_children>
283 <max_spare_children>2</max_spare_children>
287 <!-- Where necessary, override the default settings here in the app_settings element. -->
289 <!-- The OAI endpoint. The domain is the name of your proxy or frontend opac website. -->
290 <!-- <base_url>http://mydomain.org/opac/extras/oai</base_url> -->
292 <!-- <repository_name>My organization(s)</repository_name> -->
293 <!-- <admin_email>admin@mydomain.org</admin_email> -->
295 <!-- The maximum number of records in a ListRecords and ListIdentifiers response. -->
296 <!-- <max_count>50</max_count> -->
298 <!-- <granularity>YYYY-MM-DDThh:mm:ss</granularity> -->
299 <!-- <earliest_datestamp>0001-01-01</earliest_datestamp> -->
300 <!-- <deleted_record>yes</deleted_record> -->
301 <!-- <scheme>oai</scheme> -->
302 <!-- <repository_identifier>mydomain.org</repository_identifier> -->
303 <!-- <delimiter>:</delimiter> -->
304 <!-- <sample_identifier>oai:mydomain.org:12345</sample_identifier> -->
305 <!-- <list_sets>false</list_sets> -->
308 The metadataformat element contains the schema for the oai_dc and marcxml metadata formats.
309 Each schema needs a reference to an xslt document.
310 You can replace them with your custom xslt stylesheets.
311 Place those in the /<openils sysdir>/var/xsl folder.
312 You can also extend the OAI2 service further with new metadata schema.
314 Bibliographic and authority records share the same stylesheet.
315 Should you want to render them differently, use the
316 marc:datafield[@tag='901']/marc:subfield[@code='t']
317 value to identify the record type. -->
322 <namespace_uri>http://www.openarchives.org/OAI/2.0/oai_dc/</namespace_uri>
323 <schema_location>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</schema_location>
324 <xslt>OAI2_OAIDC.xsl</xslt>
327 <namespace_uri>http://www.loc.gov/MARC21/slim</namespace_uri>
328 <schema_location>http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd</schema_location>
329 <xslt>OAI2_MARC21slim.xsl</xslt>
331 </metadataformat> -->
334 You can add different schema to the metadataformat element thus:
336 <namespace_uri>http://www.loc.gov/mods/</namespace_uri>
337 <schema_location>http://www.loc.gov/standards/mods/mods.xsd</schema_location>
338 <xslt>my-custom-marc2mods.xsl</xslt>
341 <namespace_uri>my-namespace_uri</namespace_uri>
342 <schema_location>my-schema_location</schema_location>
343 <xslt>my-marc2my-metadata.xsl</xslt>
344 </my-metadata_prefix>
347 <!-- Change the way the asset copy values are mapped to which subfield codes: -->
358 <!-- Or add static values to the copies element like this:
359 <z>A value that always should for example be in the 852$z</z>
362 <!-- Accept only 852$[barcode] values that match this regular expression. E.g.
363 <barcode_filter>^[A-Za-z0-9]+</barcode_filter>
364 only renders 852 datafields that contain barcodes values that begin with letters and numbers.
366 <barcode_filter><barcode_filter>
369 <!-- Accept only 852$[status] values that match this regular expression. E.g.
370 <status_filter>^Available$</status_filter>
371 only renders 852 datafields that contain status code values that exactly match the string 'Available'.
373 <status_filter></status_filter>
380 ==== 3.2 Activate the service
382 Refer to the service in the opensrf.xml's activeapps element:
386 <appname>open-ils.oai</appname>
389 ==== 3.3 Register the service with the router
391 Add the service to the public router with your /<openils sysdir>/conf/opensrf_core.xml
398 <domain>public.realm</domain>
400 <service>openils.oai</service>