OpenURL Object Model
October 10, 2008
djatoka and the OpenURL Object Model (OOM)
About two years ago, I announced an open-source alpha Java implementation of OpenURL 1.0 called the OpenURL Object Model (OOM). Beyond a few cryptic blog posts, documentation was non-existent. But since the Java classes reflected the OpenURL 1.0 data model, it was theoretically possible for someone familiar with OpenURL to make use of them.
To prove this unlikely claim, the Los Alamos National Laboratory, Research Library recently announced djatoka, an open-source JPEG 2000 image server. I especially like that djatoka challenges the prevailing conception that OpenURL is just a citation-linking mechanism. These folks obvious understand OpenURL inside and out, but I am still amazed that they used OOM for their low-level infrastructure with little more than its source code to guide them. That is hard core!
The fact that two years has elapsed since I announced the alpha version of OOM does not mean I have forgotten about it. On the contrary, OOM was immediately employed as the foundation for the WorldCat Registry and has been handling new use cases with barely a flinch ever since. Granted, the WorldCat Registry may not look like an OpenURL resolver on its surface, but thanks to djatoka it may now be possible for people to believe there is more potential to OpenURL than its citation-linking history suggests.
September 17, 2006
Problems with the ContextObject Model
In my last post, I said that there were too many subtle issues surrounding ContextObjects for me to be completely comfortable with them. In the end, though, I think we can do much to clarify these issues for advanced users, and hide them completely from novices.
After dismissing the Referrer and Resolver Entities as a ding and a toot in that post, let me revive them briefly as a case in point. Unlike the other Entities, I couldn't imagine convenient Q6 interrogative labels for these two. I don't think this is a coincidence. These two Entities serve a significantly different purpose from the remaining Entities that are dedicated to conveying the actual details of the request. Referrers and Resolvers are peculiar to the situation where these details can be decoupled from any particular resolver. The Resolver Entity in particular makes sense as a formalized conceptual model to represent this decoupling, but as far as I know we rarely ever expect them to be manifested in an actual ContextObject Representation. Instead, it is implied that independent intermediaries will generate a link to a local Resolver without regard to using or embellishing Resolver Entities. Referrers suffer from similar issues. Under the circumstances, I think it would have been clearer to create some structure within the ContextObject to segregate these two from the others. Now that I see this in print, though, I have to admit that this is mostly a quibble. Nevertheless, I think it's good for us to be aware of these things. Let's move on to more substantive problems.
ContextObjects are also befuddling because conventional ContextObject Representations often aren't adequate to represent them. I hinted at this in an earlier post. 1) Take data stored in cookies, for example. 2) As another example, a Referrer wouldn't generally fill in a ReferringEntity descriptor when it publishes a ContextObject Representation because that job is deferred to the intermediary that generates the Transport link. Even then, I don't see the need for the intermediary to add in such a descriptor to the links it generates because the Resolver might just as well pull this information from the HTTP 'Referer' header instead. 3) Likewise, a Resolver would be foolish to trust a naked Requester Entity that it finds in a ContextObject Representation. These are too easily spoofed. A more likely scenario is that a client would start with a request to an OpenURL authentication service with the userID and encrypted password descriptors in the Requester Entity. If these pass muster, I can imagine the Resolver storing that userID in a session object and automatically pulling it from there with every subsequent request, regardless of what the client might claim their userID to be in those subsequent ContextObject Representations.
The good news for ContextObjects is that all the problems in this last paragraph evaporate from the OpenURL Object Model POV. The difference is that the preceding analysis assumes the conventional network-level vantage point where ContextObject Representations must be platform- and language-independent and spoofing is a concern, whereas in OOM this isn't the case. OOM applies the OpenURL model at the machine level rather than the network level. Internal to OOM, the ContextObject Representation is always the OOM ContextObject class. The scenarios I listed that are treated with a wink and a nod by conventional ContextObject Representations can be treated with bona fide descriptors once the OOM Transport class has its say in the matter (i.e. pulling data from the network-level ContextObject Representation, cookies, sessions, and headers).
To summarize, it seems that it's not ContextObjects themselves that are the problem so much as it is the ContextObject Representations. In the Q6 model (like in most web applications), the ContextObject Representation is implied in the Transport (=Q6:"How") such that most people wouldn't notice it as a discrete component. I appreciate that the OpenURL committee saw fit to decouple it as an advanced feature, but I don't think we should go out of our way to promote it to beginners.
September 15, 2006
Oversights in OOM
While reviewing my last post, I suddenly realized that the current alpha version of OOM-J assumes a server-side perspective. I will try to adjust the models as soon as I can to support client-side use of OOM as well. While I'm at it, perhaps I can add changes so developers can build stand-alone applications using the OpenURL models. Why weren't these omissions obvious to me before?
September 10, 2006
Two Levels of OpenURL
The models defined by OpenURL can be applied at two separate levels: the network level and the application level. The enduring legacy of OpenURL 0.1 is that most people still envision OpenURL as a linking mechanism between clients and servers (the network level) with ContextObjects as the intermediary. The OpenURL Object Model (OOM) tackles the application level. In addition to accepting ContextObjects from the client, it also uses them within the application as a bridge between the decoupled server and pure business logic. Here's the general flow:
- The client "serializes" a ContextObject and "transports" it to a OOM-compliant server
- On the server, an OOM Transport extracts an OOM ContextObject and optionally enriches it with additional information (e.g. from session data or cookies)
- OOM relays the enriched ContextObject to the requested OOM Service class for processing
- The Service class extracts descriptors from the enriched ContextObject, uses it to invoke some business logic, and transforms the business logic response into a standardized response
There are several points worth highlighting.
- In bullet 1, the client doesn't need to know that the server is OOM-compliant because the ContextObject is a general abstraction
- Likewise in bullet 3, the server doesn't need to know the specifics of the Services because the ContextObject is a general abstraction
- I also want to remind people not to think too narrowly about the meaning of "serialization" and "transport" in bullet 1 because these are extensible in the OpenURL Registry. In other words, practically any imaginable web service request can be made OpenURL-compliant by adding a few entries to the registry.
I stated the revolutionary benefit of using OOM in my last article
. Since there was no reaction, I'll repeat it. OOM practically allows developers to drop their raw business logic on a server's classpath and have it "magically" appear as a web service. A correlary of this is that a developer should be able to bundle an entire OpenURL application into a jar file and distribute it as a drop-in module to any (language-dependent) OOM installation. It also means that sets of services could be bundled together and installed as drop-in modules to add new features to existing applications. Web services can't possibly get any easier to create than that.
August 20, 2006
Using OOM to Create Web Services
The reputation that OpenURL is too complicated is totally undeserved. At the heart of OpenURL are six questions that any three year old could understand (e.g. "What is your dog's name?"). These questions are usually all programmers need to convey the essence of a web service request.
Having conveyed this information, though, what does OpenURL have to say about operating on it? According to the OpenURL Object Model, application developers are generally responsible for implementing three components:
- Business logic: Programmers can name methods anything they like, accept any parameters they need, and return any result that makes sense.
- Transport: This class takes a request (e.g. HttpServletRequest) and transforms it into its Q6 equivalent (viz. who, what, where, why, and when).
- Service: This class takes the Q6 information created by the Transport class and reformulates it into the kinds of parameters expected by the business logic, invokes the business logic, and transforms the business logic result into a standard response type.
David Wheeler is quoted as saying "Any problem in computer science can be solved with another layer of indirection. But that usually will create another problem." This is the role played by the six questions and why the Transport interface is separate from the Service interface. OOM has nothing whatsoever to say about how the business logic is structured, and that is a very good thing indeed. In essence OOM is just a little bit of glue that can turn your business logic into web services. It's fair to say this added level of indirection creates a new set of problems, but they are manageable. More can be said about these consequences later.
August 7, 2006
I have a "Hello World" demo available to get people started with OOM. Here is the relevant CVS information:
This module contains an Ant build file to deploy the project to a Tomcat webapp named "q6Demo". You can then access it from something like http://localhost:8080/q6Demo/. I also include a JUnit test case to exercise the Hello service class directly. The module also contains oomsrc.jar and oomRefsrc.jar files that can be used for debugging purposes.
Once this is working, you can use the Hello.java source as a starting point for new OpenURL services and SimpleHow as a starting point for new OpenURL Transports.
August 7, 2006
Seeing the Big Picture
The first thing to notice is that OpenURL 1.0 blows the doors off of OpenURL 0.1. OpenURL is no longer limited to citation linking. The abstractions provided in the OpenURL 1.0 model extend its range to encompass any imaginable web service. Not enough people realize the significance of this.
Imagine that I write a Java method that contains pure business logic. I want to name my method anything I like, accept any parameters I need, and return any result that makes sense. Now, imagine that I could drop this on the classpath for a Tomcat webapp and have it magically appear as a web service. OpenURL 1.0 gives me that ability with a minimal amount of code to glue things together.
Given this view of OpenURL, OOM is intended to standardize this glue. I should be able to create a set of web services and bundle them together in a jar file distribution. People could then download the jar and drop it into any OOM-compliant OpenURL resolver to install them.
For example, my local library's web site contains a list of upcoming events, but they don't offer an RSS feed. If they had an OOM-compliant resolver installed, I could write such an RSS service for them and ask them to plug it into their resolver without me having to know which OpenURL implementation they were using.
Most people don't think of OpenURL as a plug-in web service architecture yet, but I believe they should.
August 7, 2006
OpenURL Object Model (OOM)
At the code4lib conference this spring, the idea came up that it would be useful to have a set of OpenURL interface classes that were analagous to XML's DOM. I finally got around to creating an alpha version in Java that I called OOM-J. I also created a Java reference implementation that I called OOMRef-J.
I did a walkthrough of some application code that uses OOM last week for my collegues at RLG. In the process, it became clear that the alpha version still has warts that caused some confusion (viz unexpected parameters). Sorry. I'll see what I can do to streamline things. Some pictures wouldn't hurt either.
It would be great to get feedback on the OOM distributions from the broader OpenURL community. That might not happen, though, until after OCLC/RLG develops an application or two using the model before the OpenURL community can be convinced of the benefits.
Alas, I made the situation even more confusing for my RLG audience by exposing them to a variant of OOM-J and OOMRef-J that used the Q6 terms in place of the official OpenURL terms. At one time I thought this would be the only way to make OpenURL palatable to programmers. The willingness of RLG to forgo the Q6 crutch convinces me that perhaps the OpenURL terminology isn't as bad as I thought as long as you have a Q6 cheatsheet pinned to your wall.