Table of Contents
Evergreen Developer Overview
Developing for Evergreen can be a challenge for those new to it. Each piece of Evergreen requires different skills, and many things will require multiple parts of the system be modified.
A basic overview of the system shows three distinct areas that one would develop in:
- OpenSRF, forming the backend communication layer for Evergreen. Primarily dealt with via Perl modules, but also including C.
- PostgreSQL Database, both in database design and stored procedures. Most stored procedures are written in SQL, PL/pgSQL, or Perl.
See also the Evergreen Technical Diagram.
OpenSRF and Services
Evergreen is built upon the Open Scalable Request Framework, or OpenSRF (pronounced "open surf"). OpenSRF provides communication between various "Applications" and the clients that wish to call them. Each application provides a service, and usually the applications are referred to as services because of this.
OpenSRF currently works by passing JSON messages over XMPP, although in the future that could change. In general the inner workings of OpenSRF are not exposed to clients and services written on top of it, so that the underlying elements can change without having to re-implement the entire system.
A very basic view of how a message passes through the system is as follows:
- A request for a service is sent to the router
- The router chooses a listener and sends the request on
- The listener passes the message onto a drone
- The drone acts on the message and sends the response back to the original requester
The Staff Client, OPAC, and some other parts of Evergreen are technically OpenSRF clients. The Staff Client and JSPac talk through the HTTP Translator, and the TPac is a Perl client embedded in the HTTP server.
Perl clients intended for use via HTTP protocols tend to be implemented in the OpenILS::WWW namespace.
In addition, OpenSRF Applications are clients as well, able to make requests to other running applications.
Most OpenSRF development will be in the OpenSRF Application area. Most OpenSRF and Evergreen services are written in Perl, but a few are written in C for performance reasons.
The list below is an overview of each application by the service name it is assigned. Included is the language the application is implemented in and which (if any) of the Public and XML-RPC interfaces it is exposed via. Public exposed services are available via the HTTP gateways.
- opensrf.settings (Perl)
- Handles loading, parsing, and distributing configuration file information. This can include things like database connection information.
- opensrf.math (C, Public, XML-RPC)
- Primarily for testing use, this service accepts requests and passes them on to the opensrf.dbmath service. Success demonstrates that not only can requests be sent and answers received but that services can communicate with each other.
- opensrf.dbmath (C, XML-RPC)
- Primarily for testing use, this service does the actual processing for the opensrf.math service.
- opensrf.validator (Perl)
- Implements a set of configurable validator chains for various data, such as email addresses.
- open-ils.acq (Perl, Public)
- The Evergreen Acquisitions module.
- open-ils.actor (Perl, Public, XML-RPC)
- Public and Staff Client access to user and org unit information.
- open-ils.auth (C, Public, XML-RPC)
- Authentication service. Implemented in C for performance reasons, handles logins and authentication token validation.
- open-ils.booking (Perl, Public)
- The Evergreen Reservations module.
- open-ils.cat (Perl, Public, XML-RPC)
- The Evergreen Cataloging module, handling creation and editing of bibliographic and asset information.
- open-ils.circ (Perl, Public, XML-RPC)
- The Evergreen Circulation module, handling checkins and checkouts, as well as Hold related information.
- open-ils.collections (Perl, Public, XML-RPC)
- The Evergreen Collections module.
- open-ils.cstore (C)
- CStore is a database search and retrieval service, and the default target for the CStoreEditor Perl class. It does not check or require authentication tokens. It can be used to perform complicated queries via json_query calls.
- open-ils.ebook_api (added in 2.12)
- open-ils.fielder (Perl, Public)
- Currently unused(?) service for loading FieldMapper information.
- Handles ingest of bibliographic records. Replaced by database triggers and stored procedures.
- open-ils.hold-targeter (added in 2.12)
- open-ils.justintime (Perl, XML-RPC)
- Action/Trigger revalidator for use with things like external telephony.
- open-ils.pcrud (C, Public)
- PCrud is a database search and retrieval service that checks and requires authentication tokens to control access to information.
- A wrapper around the OpenILS::Utils::Penalty module for calculating patron penalties.
- open-ils.permacrud (Perl, Public)
- A Perl authentication checking wrapper around CStore calls.
- Executes database queries that have been previously defined, in an abstract form, within the database itself.
- open-ils.reporter (Perl, Public)
- The Staff creation and query service for the reports system.
- open-ils.reporter-store (C)
- Effectively CStore with a different name, so as to support a different set of IDL tables.
- open-ils.resolver (Perl, Public)
- OpenURL holdings retrieval service. Note: Disabled by default.
- open-ils.search (Perl, Public, XML-RPC)
- Searching related functions, including Catalog and Z39.50.
- open-ils.serial (Perl)
- Serials-related tasks such as receiving items and generating predictions.
- open-ils.storage (Perl)
- Direct database calls for various actions, intended in part to support databases other than PostgreSQL at some unspecified point in the future that will likely never come. Similar to a Perl-based CStore, but with more utility functions included.
- open-ils.supercat (Perl, Public)
- Additional search and browse routines for various catalog elements, such as authorities, subjects, topics, call numbers, etc.
- open-ils.trigger (Perl)
- The Action/Trigger subsystem, responsible for various notices and other automated tasks based on things such as circulation due dates, holds being available and/or canceled, etc and so forth.
- open-ils.vandelay (Perl, Public)
- The bib import/export/overlay module.
Evergreen uses PostgreSQL as a storage backend and makes somewhat heavy use of many PostgreSQL features. PostgreSQL databases are split into schemas, allowing for logical groupings of related information. For configuration recommendations, see Optimizing the performance of your Evergreen server.
In addition to PostgreSQL itself one should also be aware of the Fieldmapper IDL, which is one of the ways Evergreen is told how to interact with the database.
Many of the schemas are obviously named, and as such do not need much description. Others cover things that are more abstract. Below is a list of all schemas currently used by Evergreen.
- This is a default PostgreSQL schema. No tables should be created here, although some generic functions are. New generic functions should be created in the evergreen schema, however.
- This is where Acquisitions specific data and functions live.
- The action schema is used for storing data on things that have happened or are going to happen, such as Circulations, Holds, Surveys, and Transits. Note that reservation related information is stored in the booking schema, however.
- This is where all Action/Trigger related information is stored, from event definitions to outputs.
- Actor covers Org Units and Users and information about them.
- Asset includes call numbers (volumes) and copy information. In addition, URI information is stored here as they are linked to call numbers.
- The auditor schema contains non-acquisitions auditing information. Beyond functions for creating auditors nothing should be manually created here. Instead call the create_auditor function to create the auditor tables, views, and triggers.
- The authority schema covers all authority related information and functions.
- The biblio schema is for bib records and related items. Note that most search and other indexing actually happens in the metabib schema.
- The booking schema covers the reservation system's information.
- Most (but not all) configuration related tables live in the config schema. The tables are commonly used as lookup tables for values stored elsewhere.
- The container schema is the storage location for buckets. Note that OPAC Bookbags/Lists are a type of biblio record entry bucket.
- A generic schema mainly for holding generic functions. Ideally tables and views should be created elsewhere.
- For the most part the extend_reporter schema is intended for local table, function, and view additions for reporting purposes.
- The metabib schema holds pre-parsed metadata about bib records, including search information, pre-extracted MARC data, and facet data.
- The money schema contains billing and payment information for billable actions throughout the system. Note that the action.circulation and booking.reservation tables inherit the money.billable_xact table.
- Evergreen contains a built-in offline mode. The offline schema handles information about processing of the offline circulations.
- Permission covers all of the permissions and permission groups in the system. Note that user profile groups are actually permission groups.
- The query schema houses data for the Query Store (qstore) service.
- Evergreen's reports interface stores its data here, and some helpful views are kept here.
- The search schema's major function is to hold the query_parser_fts function.
- Information on serials (like magazines) is stored in the serial schema. Note that serial.unit is inherited from asset.copy.
- The staging schema is used to stage potential new users, complete with addresses, cards, and statistical category entries.
- The stats schema is created alongside the config schema, but is currently unused.
- Information and functions pertaining to unapi output is stored here.
- The vandelay bib import/export/overlay system stores its data here.
Fieldmapper maps database fields to Evergreen objects.
The Fieldmapper IDL, or just IDL for short, is the Fieldmapper configuration file (fm_IDL.xml) which tells Evergreen about all of the important aspects of the database. It is comprised of a set of class nodes, each of which contains at minimum a list of fields. In addition, each class may contain links, permissions, and in the case of fully virtual classes a block of SQL that defines the data to be retrieved.
An important note: For the most part, clients and services can only talk to database elements that are defined within the IDL. The notable exception is stored procedures, which are not listed in the IDL.
One of the benefits of using Fieldmapper is that it generates object code for each of the objects defined in the IDL, which allows us to create those objects from within Evergreen and use them to access their respective database tables and views. Also, for classes in the IDL with a controller of "open-ils.cstore", the CStoreEditor creates CRUD methods (to Create, Retrieve, Update, and Delete) and a search method (e.g. $editor->search_biblio_record_entry(), or $editor->update_actor_user()).
TPAC development thus comes in two flavors:
- Perl "backend" code in the OpenILS::WWW modules for processing and data retrieval
- Template Toolkit template code in the Templates directory for formatting and display
JSPAC (no longer included as of Evergreen 2.9)
The JSPAC supported multiple skins, but only one shipped with Evergreen.
The Evergreen browser-based (or "web") staff client is now the main client, and the XUL client is not supported starting with Evergreen version 3.2 (Fall 2018). Because of this, Evergreen 3.1 has an extended support window for sites that are not ready to switch to the web client.
External Code - SIPServer
In addition to the core OpenSRF and Evergreen code there are other projects commonly used with Evergreen that may require work for development projects. The most common is currently SIPServer, which provides a SIP2 interface for Evergreen that can be used with Self Check units, Automated Materials Handlers, PC Reservation systems, and some third party services for authentication.
SIPServer is maintained as a separate project, is written in Perl, and interacts with Evergreen through the OpenILS::SIP Perl package.
In addition to the information listed in the contributing document at http://evergreen-ils.org/dokuwiki/doku.php?id=contributing there are a number of things to consider.
First and foremost, stay visible and communicate so that others watching your work know you are making progress. If you don't, and are hard to contact, your project may be deemed "abandoned" and someone else may jump in. This is not only potentially frustrating for you if they release their code first, but to them if you suddenly "return" with your work. Either way someone has likely wasted effort that could have gone to other tasks.
As part of that, if you are having issues ask questions, be it on IRC or via the mailing lists. IRC is most useful during the day in the United States/Canada Eastern Time Zone (GMT-5, or -4 during DST), but the mailing lists are usable anytime (though can be slow to get responses).
If you have opened a Launchpad bug keep it up to date. In addition, excepting security issues, you should prefer the public channels over direct communication with individuals. Not only does that ensure that others know you are still there and working on the issue, but you also get the benefit of the community's knowledge (and contribute to it via archives).
As a note on communication via Launchpad, when responding to things on Launchpad via email sometimes Launchpad "eats" messages, grabbing the wrong part of the message for one reason or another, usually signature-related. Thus it is recommended that you double-check your first few email responses to ensure that they made it through to the bug in question.