Archive for the ‘OpenSRF’ Category

Community Update: New Features in 1.4 and Platform Heads-up

Wednesday, July 16th, 2008

This post offers a heads-up about features in Evergreen 1.4, the next major Evergreen release, due out by early fall 2008, and also offers some information specific to PostgreSQL and OpenSRF.

New features in Evergreen 1.4

Internationalization support for the OPAC and staff client. User interfaces, messages, currencies, dates, etc. will all be displayed according to the chosen locale of the user, and will be able to be switched dynamically. We will need translators; a call for volunteer translators will go out soon!

Online payments, originally scheduled for the 2.0 release, will actually be introduced in the 1.4 release this summer, thanks to the contribution of Niles Ingalls at Hussey-Mayfield Memorial Public Library in Zionsville, IN.

Z39.50 and SRU server support. Evergreen will now be able to act as a Z39.50 server and a SRU server — an important feature for interlibrary loan, federated search, and other library applications.

Ability to search across defined groups of libraries, rather than just hierarchical sets of libraries (affectionately called “org_unit lassos” because they bind arbitrary sets of org_units together in a single search group)

Reminder notices, also known as pre-overdue notices, will be part of the 1.4 release.

Record loading in 1.4. Just to clarify, bibliographic data will still need to be loaded in MARC21 format; libraries that currently have UNIMARC data will need to convert it to MARC21 using a tool like MARCON to use Evergreen.

Platform heads-up for Evergreen 1.4

PostgreSQL 8.2 for Evergreen 1.4 (dropping support for PostgreSQL 8.1, no official support for PostgreSQL 8.3 yet). PostgreSQL 8.2 offers better performance and some significant feature enhancements over PostgreSQL 8.1; therefore, we strongly suggest that any new sites deploy Evergreen on PostgreSQL 8.2 and will be dropping support for PostgreSQL 8.1 with the Evergreen 1.4 release this summer.

PostgreSQL 8.3+ for Evergreen 2.0

We are currently working on adding support for PostgreSQL 8.3, which brings even more performance and feature enhancements to the table, but which also requires a refactoring of some of our code base. Therefore, we are holding off on official support for PostgreSQL 8.3 until the Evergreen 2.0 release in the spring 2009 time frame, to ensure that the changes have been thoroughly tested.

OpenSRF 1.0 for Evergreen 1.4

OpenSRF 1.0 will be the minimum required version for Evergreen 1.4. (Open Service Request Framework, pronounced “open-surf,” is the software architecture at the core of Evergreen, invented by Evergreen’s developers.)

OpenSRF 0.9 has served us well since July 2007, but the performance enhancements, new features (such as OpenSRF-over-HTTP), and usability improvements in OpenSRF 1.0 make it a mandatory upgrade. The build system for OpenSRF 1.0 has been standardized with the use of autoconf & automake, so installing and configuring OpenSRF 1.0 will be a snap.

(Special thanks to Dan Scott for help with this post!)

It’s the newwwwwww style

Friday, July 6th, 2007

This afternoon, rather quietly, I posted the first release candidate for Evergreen 1.2.0 on the Open-ILS.org download page. This is a big milestone for the project and for the developers. It’s also a big milestone for those interested in adopting Evergreen outside of PINES. The 1.0 series was pretty heavily skinned for PINES, with the images, rules, and default configuration, and new backend features were slow to be incorporated due to the pain of updating the database schema. The shiny new 1.2 series removes almost all traces of PINES-specific images and default rules, and contains many new backend improvements. It is also the first non-experimental release to include a significant amount of code not created directly by GPLS and PINES.

(more…)

Escape!

Thursday, December 7th, 2006

In case anybody happens to need some C that can take a char* and encode any UTF-8 byte sequences in there (as I needed to — our cribbed UTF-8 encoder proved brittle), here’s a little bit of code that may help. It’s probably more verbose than it needs to be, but it works — and working code wins! :)
(more…)

Insert Clever Snake Metaphor

Friday, December 1st, 2006

In an effort to maintain some mental stimulation while we go through our post-migration shake-down (i.e. Bugzilla and feature request wrangling), I’ve decided to learn Python in the off-hours. I also figured while I was at it, I might as well get some useful code out of it.
(more…)

Quicker SuperCat update

Thursday, March 9th, 2006

I said coming soon, and I meant it! ;) Here’s the HTML output from an OpenSearch 1.1 Atom feed, rendered server side to include unAPI.

So, here’s the stack that generates that page

  • The open-ils.storage OpenSRF application acts a distributed ORM for all of OpenILS’s persistent storage needs.
  • We have applications called open-ils.search and open-ils.actor that give simple access to raw search methods, as well as library and user lookups (actors).
  • My shiny new open-ils.supercat application provides a simpler interface to the catalog portions of the storage application
  • The mod_perl module that gives open-ils.supercat a friendlier API lives here, and is slowly but surely growing an appendage that’s shaped like a generic XML feed generator.
  • The html “feed” type is actually an Atom feed that has its own special toString method that pushes the Atom through a hacked up version of A9’s atom->html XSLT before it gets sent off to your browser. I added the ability to expose the unAPI links and identifiers I embed in my Atom OS output, as well as tweaked the layout a bit, but basically it’s what A9 put out under a Creative Commons license.
  • Then, just to make IE happy, there’s a client side XSLT that essentially replaces the entire content of the page with a copy of itself. No, I’m not kidding. I had to do that to get this thing working in IE.

Anyway, someone with more UI skillz can come along and pretty it up a bit (let’s hope they do), but it works, and it only took about an hour — aside from my epic battle with IE — to get it working mostly the way I wanted. This bodes well, methinks, for the future of SuperCat and the write-oriented interfaces I have planned.

Now I just need to find an artist to create a great logo! Dan suggests “a super-hero cat wearing a cape, and the cape should have an iconic logo of itself on the cape… napping.” Sounds good to me. Anyone know a good artist that likes cats and OSS?

Quick SuperCat update

Wednesday, March 8th, 2006

What its web API can do today:

  • REST retrieval of bibliographic records as MARCXML, MODS, atom entry, rss item, oai_dc, srw_dc and rdf_dc, as well as OPAC redirection
  • unAPI retrieval in formats above
  • OpenSearch 1.0 and 1.1, and OSD generation (yes, generation — replace the dash in those URLs with title, author, subject or series to get OSDs for searches other than “keyword”); response formats are RSS 2.0, atom, MARCXML (for the completely insane), MODS and, coming soon, HTML using atom->xhtml client side XSLT, though replacing the format with a “-”, as the OSD does, returns results in RSS for version 1.0 and atom for version 1.1. There is support for limiting searches to specific libraries or local library systems within PINES, though I haven’t yet decided on the best way to expose that functionality in the OSDs — probably an extension namespace would be best.
  • Patron book bag publishing in formats above, as well as an OPAC redirect (coming soon: standalone HTML via the same atom->xhtml XSLT as the OpenSearch feeds, in addition to OPAC redirect)
  • oISBN

All these web services are based on the relatively simple and thin OpenSRF application, open-ils.supercat, which is a wrapper to simplify part of the open-ils.storage API, and a couple calls to the open-ils.search open-ils.actor applications. All the code was built in the little time I could steal between preparing for 10 full day meetings over the past 5 weeks, and whatever time my loving, and very forgiving, wife has allowed me on the weekends when I should have been doing yard work.

Next up

  • RESTful holdings retrieval
  • RESTful create and update interface for bib records
  • RESTful notes interface (CRUD) for bib records and holdings
  • Atom Publishing Protocol create and update interface for bib records
  • More output formats for metarecords
  • RESTful update/remapping interface for metarecords
  • Once the unAPI paste spec starts to appear, an unAPI paste interface

… and lots more, I’m sure.

print “Achtung!\n”x3;

Sunday, February 26th, 2006

I’ve been particularly productive today, at least as far as externally visible services are concerned. SuperCat is proving to be a mighty beast, and is now the basis of three (count ‘em, three) shiny new web APIs.

UPDATE: Bill and I set up the services described here on our externally accessible dev server. The URLs in the body have been updated to links that point at that server.

(more…)

API Reference

Saturday, February 18th, 2006
screenshot

I mentioned in a previous post that we were planning to create a script to extract API documentation from our new OpenSRF method signature layout. Well, I was inspired by Aaron Krowne, and found guidance in Thom Hickey, to create an XSLT wrapper to the existing OpenSRF introspection API using the OpenILS XML Gateway.

It’s still only available for use on my development server, but it’s in cvs for all to see, or you can click on the unreadably tiny image at the top left of this post for a screenshot. It’s a (some would say scary) mix of XSLT and Apache SSI, but it’s fast and does what we need. It is currently based, as I mentioned, on the OpenILS XML Gateway, so it’s not really part of OpenSRF proper. I plan to remedy that shortly by pulling the OpenILS specific parts of the XML Gateway out into their own library, and creating a generic OpenSRF XML Gateway.

If anyone out there with free time, a love of XSLT and a desire to help out with OpenSRF or OpenILS/Evergreen would like to poke at it, be my guest. Be forewarned, though; if you are experienced with XSLT (which I most certainly am not) it may make your eyes bleed.

UPDATE: For those interested, I asked Bill to push the docgen XSLT out to our dev site, and, well, he did. You can see it in action here.

Running the gauntlet: Volume 1

Tuesday, February 14th, 2006

I began work on open-ils.supercat this weekend, and things are going swimmingly so far. I created the open-ils.supercat.record.marcxml.retrieve and open-ils.supercat.metarecord.mods.retrieve methods with no problem, and added open-ils.supercat.record.mods.retrieve as well. The metarecord building code is mostly a big pile of DOM, but you can see the code here in the sub called retrieve_metarecord_mods if you are so inclined. The record methods, both marcxml and MODS, are much leaner, so I’ll show those inline:

sub retrieve_record_marcxml {
	my $self = shift;
	my $client = shift;
	my $rid = shift;

	return
	entityize(
		$_storage
			->request( 'open-ils.storage.direct.biblio.record_entry.retrieve' => $rid )
			->gather(1)
			->marc
	);
}

__PACKAGE__->register_method(
	method    => 'retrieve_record_marcxml',
	api_name  => 'open-ils.supercat.record.marcxml.retrieve',
	api_level => 1,
	argc      => 1,
	signature =>
		{ desc     => < <"		  DESC",
Returns the MARCXML representation of the requested bibliographic record
		  DESC
		  params   =>
		  	[
				{ name => 'bibId',
				  desc => 'An OpenILS biblio::record_entry id',
				  type => 'number' },
			],
		  'return' =>
		  	{ desc => 'The bib record in MARCXML',
			  type => 'string' }
		}
);

sub retrieve_record_mods {
	my $self = shift;
	my $client = shift;
	my $rid = shift;

	my $marc = $_storage->request(
		'open-ils.storage.direct.biblio.record_entry.retrieve',
		$rid
	)->gather(1)->marc;

	return entityize($_mods_sheet->transform( $_parser->parse_string( $marc ) )->toString);
}

__PACKAGE__->register_method(
	method    => 'retrieve_record_mods',
	api_name  => 'open-ils.supercat.record.mods.retrieve',
	api_level => 1,
	argc      => 1,
	signature =>
		{ desc     => < <"		  DESC",
Returns the MODS representation of the requested bibliographic record
		  DESC
		  params   =>
		  	[
				{ name => 'bibId',
				  desc => 'An OpenILS biblio::record_entry id',
				  type => 'number' },
			],
		  'return' =>
		  	{ desc => 'The bib record in MODS',
			  type => 'string' }
		}
);

As you can see, in both cases the method registration call containing the method signature is larger than the actual sub even with a great deal of whitespace in the code. I will take that as a good sign, since that signature allows scripted API documentation, basic argument checking (that I don’t have to handle inside the method) and quick-glance documentation inline in the code.

Record groups? We got your record groups!

Tuesday, February 14th, 2006

While we don’t have the many millions of records that OCLC does (what, 60M+?), we do have a local database to play with, an extensible ILS, and the desire to do fun stuff like OCLC does. So, I wrote an xISBN clone while working on the open-ils.supercat OpenSRF application. Instead of grouping records into FRBR work-sets, we group records into OpenILS/Evergreen metarecords. That is the algorithm that works best for PINES, but the metarecord fingerprinting algorithm will soon be scriptable via server-side JavaScript (complete with DOM and XPath for processing MARCXML records), and we plan on creating a FRBR-ish version at some point based on that work.

One big advantage of our version is that it works using the live data we already have indexed, so there’s no need to create a specialized database that can get stale over time. In fact, every extension we write will work that way if at all possible.

I think it’s a pretty good example of an OpenSRF extension to OpenILS that a developer with a mild familiarity with the open-ils.storage server could create. I’ll be posting the code for the mod_perl handler that creates the XML version soon — all 10 lines that I expect it will take. Anyway, here’s the code:

sub oISBN {
	my $self = shift;
	my $client = shift;
	my $isbn = shift;

	throw OpenSRF::EX::InvalidArg ('I need an ISBN please')
		unless (length($isbn) >= 10);

	# Create a storage session, since we'll be making multiple requests.
	$_storage->connect;

	# Find the record that has that ISBN.
	my $bibrec = $_storage->request(
		'open-ils.storage.direct.metabib.full_rec.search_where.atomic',
		{ tag => '020', subfield => 'a', value => { like => $isbn.'%'} }
	)->gather(1);

	# Go away if we don't have one.
	return {} unless (@$bibrec);

	# Find the metarecord for that bib record.
	my $mr = $_storage->request(
		'open-ils.storage.direct.metabib.metarecord_source_map.search.source.atomic',
		$bibrec->[0]->record
	)->gather(1);

	# Find the other records for that metarecord.
	my $records = $_storage->request(
		'open-ils.storage.direct.metabib.metarecord_source_map.search.metarecord.atomic',
		$mr->[0]->metarecord
	)->gather(1);

	# Just to be safe.  There's currently no unique constraint on sources...
	my %unique_recs = map { ($_->source, 1) } @$records;
	my @rec_list = sort keys %unique_recs;

	# And now fetch the ISBNs for those records.
	my $recs = $_storage->request(
		'open-ils.storage.direct.metabib.full_rec.search_where.atomic',
		{ tag => '020', subfield => 'a', record => \@rec_list }
	)->gather(1);

	# We're done with the storage server session.
	$_storage->disconnect;

	# Return the oISBN data structure.  This will be XMLized at a higher layer.
	return
		{ metarecord => $mr->[0]->metarecord,
		  record_list => { map { ($_->record, $_->value) } @$recs } };
}
__PACKAGE__->register_method(
	method    => 'oISBN',
	api_name  => 'open-ils.supercat.oisbn',
	api_level => 1,
	argc      => 1,
	signature =>
		{ desc     => < <"		  DESC",
Returns the ISBN list for the metarecord of the requested isbn
		  DESC
		  params   =>
		  	[
				{ name => 'isbn',
				  desc => 'An ISBN.  Duh.',
				  type => 'string' },
			],
		  'return' =>
		  	{ desc => 'record to isbn map',
			  type => 'object' }
		}
);

Code, document thyself!

Tuesday, February 7th, 2006

In an effort to help others (and ourselves) write cleaner, happier, more eco-friendly code, we have added optional argument count and signature checking to OpenSRF. To make using this facility as simple and unobtrusive as possible there are three implementation levels (well, four if you count “a short note without parameter information”), each one more descriptive than the previous, so developers can choose how much (if any) time they will invest in documenting method signature and use and whether runtime argument checks are appropriate for that method. The other part is the argc setting that can be passed along with the signature. This specifies how many arguments are required, and the code will check their type and class against the actual parameters supplied if the signature gives that much information. Eventually, signature level 3 will allow individual parameters to be marked as required, and it will allow the handling of named (instead of positional) parameter description and validation. I’ll go ahead and lay out the structure of each method signature level here, and wait patiently for my thrashing to ensue.
(more…)

Throwing down the gauntlet

Tuesday, February 7th, 2006
  • Alternative OPACs
  • Personal Card Catalogs
  • Bookbags
  • Record Tagging
  • Reading Lists
  • User built RSS Feeds of reading lists and searches
  • Interactive searches
  • Saved searches
  • Search history
  • … tons of other things we’ve collectively imagined …

What do they conceptually have in common? (more…)

OpenSRF Jabber: A Technical Review

Thursday, September 29th, 2005

As has been mentioned before on this blog, OpenSRF relies on Jabber for it’s communication layer. Jabber is an instant messaging service much like AIM, Yahoo messenger, and the like. The advantage of Jabber, of course, is that it’s an open spec (see xmpp.org) and there are a number of open source server implementations, allowing us to run servers localy and write our own server code if we feel so inclined.

Like most chat frameworks, a Jabber client is distinguished by its username on the network. So a unique Jabber “account” would consist of something like bill@gapines.org. Jabber also adds an additional component which is called the “resource”. This allows a single account to have multiple open connections to a jabber server. A full client login would be something like bill@gapines.org/home, bill@gapines.org/work, etc. A single user may be logged into a given server as many times as they want so long as the resources are unique for each connection.

(more…)

It’s turtles all the way down

Friday, August 12th, 2005

This will be a quick one because I’m feeling a bit under the weather, but I wanted to post a quick update on some of our tornado-like progress post-alpha.

(more…)

A little history on JSON, etc.

Tuesday, July 5th, 2005

I’m glad to see we’ve stirred the pot with our discussion of JSON. It’s driven us to stop and think about our decisions, their impact on our project, and how others may be able to interact with our system.

For the sake of those interested, I thought I might offer some clarity regarding our use of JSON. When OpenSRF (our core information passing framework, discussed here) was first designed, it was XML everywhere. As we were doing our benchmarking of the system, we thought things were good, but sluggish with large datasets. OpenSRF is designed as a set of independent applications which often must communicate with one or more other applications to accomplish any particular task. For example, to retrieve information on a patron, the system must verify the requesting party has such permission, then it must actually retrieve the information. With a lot of such conversation going on across the backbone, you can see there will be a great deal of data flying around the network.

(more…)

The birth of OpenSRF

Monday, February 7th, 2005

After months of work, buckets of sweat, and one snapshot of code seemingly unrelated to libraries, we are proud to present our first subproject: OpenSRF (Open Scalable Request Framework), pronounced “open surf”. The 0.1 release of OpenSRF represents the culmination of everything we have posted about here, and some things we haven’t.

One of the main differences between our initial snapshot tarball and the shiny new OpenSRF code is the removal of the dependence on an Auth Application. We have decided that the security provided by Jabber is sufficient for connection to the OpenSRF network, and application level authentication and authorization should be handled either by each individual Application, or by an Authentication Application built specifically for the target problem domain.

(more…)