Bilal Siddiqui's recent Apache Directory Server (ApacheDS) tutorial on IBM DeveloperWorks shows how to store and share Java objects via this new Apache product. ApacheDS uses MINA as a pluggable protocol layer, and has out-of-the-box LDAP support. But is LDAP always the right choice for storing shared application data, such as user accounts?
ApacheDS is an open-source directory server designed to let various client applications store and shared their data. ApacheDS is foremost an LDAP server. However, it provides a pluggable protocol layer on top of the directory—thanks to Apache MINA (Multipurpose Infrastructure for Network Applications)—and supports protocols beyond LDAP, including Kerberos and JNDI. The ApacheDS documentation mentions the possibility of supporting DNS, DHCP, SLP, and UDDI as well.
Bilal Siddiqui's recent IBM DeveloperWorks tutorial Storing Java objects in Apache Directory Server shows ApacheDS's flexibility with an example that stores Java objects in the directory via LDAP. The example uses the client-side JNDI implementation for LDAP that ships with J2SE to interact
with ApacheDS by storing, searching, and retrieving preferences:
The system allows all users to set their own preferences about the way they use the system. For example, users can customize the data to be displayed in their personal default view when using the system and apply different presentation styles to different data elements. The system also allows special preferences depending on the type of a user. For example, employees of the company (internal organizational users) can set messaging preferences, customers can set shipping preferences, and vendors can set invoicing preferences.
Such user preferences are defined by a Preferences class and its subclasses, such as ShippingPreferences and MessagingPreferences. Bilal shows a fairly straightforward mechanism to persist the contents of Java objects in an LDAP directory:
RFC 2713 ... defines object classes and attribute types to represent Java objects in an LDAP directory. ApacheDS provides complete support for these attribute types and object classes.
The article uses four such object classes:
javaContainer ... is a structural class that contains just one attribute: cn. The purpose of this object class is to name the data entry that contains the Java object...
javaObject is an abstract class [used] to define some helping attributes that are not directly used in storing the data of a Java object but are ... helpful in search operations to find or retrieve the object from the directory.
javaSerializedObject extends the javaObject class by adding just one attribute called javaSerializedData [that] contains the actual serialized form of your Java object...
LDAP also allows you to store a reference of a Java object in a directory instead of storing the actual object...javaNamingReference ... extends the javaObject class and defines two new attribute types javaReferenceAddress and javaFactory. The javaReferenceAddress attribute type stores the reference (or address) of the Java object and the javaFactory attribute type stores the name of the factory object [used to retrieve the Java object].
With a solid open-source Java LDAP server such as ApacheDS, we have two main choices for storing data that must be shared between applications and even users:
LDAP Store user and shared application data in a directory server, such as LDAP.
A custom database Store all such data in a database using a custom schema. For instance, an enterprise can have a "Users" database that stores user account information along with user preferences.
One advantage of the LDAP approach is that it can be shared by multiple applications. A system administrator can use standard LDAP tools (such as JExplorer) to manage users, alleviating the need to develop a custom user management module. The downside of the LDAP approach is the requirement to confirm to the LDAP directory schema conventions. Those conventions may not suite all application requirements. Bilal's article shows, however, that one can customize an LDAP schema with some extra work.
But if one were to invest in that extra customization work, why not just persist user information directly in a database? That database could also be shared among many applications in an enterprise. With O/R mapping tools, such as Hibernate, even a fairly complex set of user preferences and relationships can be managed with minimum coding.
A downside of the custom database approach is that it eschews standard LDAP tools, and requires a custom interface to access. That minus may be offset by the potential benefit of enforcing at the database level referential integrity that relates to shared data, such as user accounts. But that benefit is harder to realize than it would first seem.
Suppose, for instance, that a user made several forum posts in an online forum application. Over time, other users reply to those posts, forming a tree with its branches relating back to the initial poster. Removing that user from the system is no longer simply a matter of deleting the user record from a Users table: enforcing referential integrity would require dropping all user-related data items, including the tree of posts relating to the user.
Instead, such applications often leave the user as a "tombstone" in the database, disabling account access or in some other way "deactivating" the user. The requirement to not remove potentially large amounts of related application data diminishes the benefits of referential integrity in such an application.
Having a shared Users database also means that user data is partitioned away from other application data into its own database. That Users database might even run on a different host. Thus, database operations involving the Users database and related items from a different database will require distributed transactions, hardly a recipe for scalability. One solution is to replicate some user data, such as a user ID, in other databases. But then why not just insert the user's unique LDAP Distinguished Name (DN) record instead?
What are your preferences in storing shared application data, such as user accounts? Does your company use a shared LDAP directory, or do you prefer custom user databases?