OpenDS Inside_ An LDAP server embedded in your application by jlhd32

VIEWS: 353 PAGES: 25

More Info
									OpenDS Inside:
An LDAP server embedded into your application

Ludovic Poitou
Sun Microsystems, Inc.


>   Overview of OpenDS
>   Why embedding an LDAP server ?
>   How to embed OpenDS
>   Conclusion

                        LOGO SPEAKER‘S COMPANY

Overview of OpenDS
Open source project launched in July 2006
To develop an LDAPv3 based directory service
Written in Java
A small but growing community
> 38 committers
   – 15 full time developers
   – 8 full time quality engineers
> 17 contributors
> 230 users

                           LOGO SPEAKER‘S COMPANY

Build a complete LDAPv3 based directory service
> A Directory Server i.e. the data-store
> But also directory proxy services, virtual directory services...
> Consolidate data access: DSML, ...
Easy to install, use and manage
> Many service APIs
> Default implementations provided
With unmatched scalability and performance
> Both horizontal and vertical scalability
> Both Reads and Writes performance

                              LOGO SPEAKER‘S COMPANY

OpenDS 1.0 is about to be released.
Already a full LDAPv3 compliant server
> Partial support of RFC 4518 (Internationalization string preparation)
> Many standard and experimental extensions
Very configurable and extensible
Several tools to help deploying, monitoring, interacting with the server
Extensive testing
Complete and accurate User documentation

                              LOGO SPEAKER‘S COMPANY

Why Embedding OpenDS in applications ?
To provide a better “Out of the Box” experience
To reduce administration and initial configuration
To setup an optimized service for your application's needs
To reduce memory footprint by running in the same JVM
> It could be a web application container
To secure access to the data
Multi-master replication provides synchronization between instances of the
To test
> simple automatic testing of LDAP client code

                             LOGO SPEAKER‘S COMPANY

Sample Uses of Embedded OpenDS
OpenDS is already used as embedded in the following 3 open source projects:
> JBoss Portal <>
> InterLDAP <>
> OpenSSO <>
JBoss Portal and InterLDAP runs embedded versions of OpenDS in their test
> To control easily the setup of an LDAP server
> To test their LDAP support
OpenSSO embeds OpenDS
> to store its own configuration
> Could also be used for the user repository
> Enables replication to scale instances of OpenSSO with identical configuration

                             LOGO SPEAKER‘S COMPANY

What do you need ?
Requires OpenDS jar files in the classpath:
> OpenDS.jar, quicksetup.jar, je.jar
> mail.jar, activation.jar, aspectj.jar
Appropriate filesystem layout for the OpenDS components
> Simply copy the OpenDS “standalone” filesystem to a subdirectory below the
> Or define specific locations through the DirectoryEnvironmentConfig class
> The minimal requirements are:
   – An overall location for OpenDS service files
   – A configuration file in LDIF format
   – A directory with LDAP schema files
   – A directory for the lock files

                            LOGO SPEAKER‘S COMPANY

Typical file layout
config Directory containing
> Config.ldif
> Schema files
db directory to contain all databases
lib directory contains the Jar files
locks directory to hold the locks.

                              LOGO SPEAKER‘S COMPANY

DirectoryEnvironmentConfig class
The DirectoryEnvironmentConfig class let you set the aspect of the DS
configuration before reading the bootstrap configuration file:
> Overall location (also called Server Root)
> Configuration file and eventually the configuration handler class
> Schema directory, Lock files directory
> Disable Connection Handlers (OpenDS accessible only through internal calls)
> Set OpenDS threads as daemon threads

  import org.opends.server.types.DirectoryEnvironmentConfig;
  DirectoryEnvironmentConfig envConfig = new
  envConfig.setServerRoot(new File("."));
  envConfig.setConfigFile(new File(“./config”, “config.ldif”));

                            LOGO SPEAKER‘S COMPANY

The configuration file
A configuration file in LDIF format
> Default config.ldif file works
> Can be striped down to remove unnecessary features and thus reducing the
   – Disabling specific services such as Notification Handlers, Access Control
        Handlers, Loggers...
   – Disabling security services if not needed (SASL, SSL...)
   – Disabling monitoring
   – ...
> When disabled from the DirectoryEnvironmentConfig, the features' configuration
   is ignored

                            LOGO SPEAKER‘S COMPANY

Life Cycle of the OpenDS service
Application is responsible to start / stop / restart the server as necessary
EmbeddedUtils class provides the methods
> isRunning()
> startServer(DirectoryEnvironmentConfig config)
> stopServer(String classname, Message reason)
> restartServer(String classname, Message reason, DirectoryEnvironmentConfig

                           LOGO SPEAKER‘S COMPANY

Sample Server Lifecycle...
import org.opends.server.util.EmbeddedUtils;
if(EmbeddedUtils.isRunning()) {
    // Already running. Do nothing
try {
} catch (Exception e) {
    throw new RuntimeException("Error when starting the server",e);

... // Do whatever with the server


                        LOGO SPEAKER‘S COMPANY

How to interact with the server
Use LDAP like with any directory server
> Using JNDI or Mozilla LDAP Java SDK
> Connect over TCP/IP
> Allows to be server agnostic
Use OpenDS Internal operations
> InternalClientConnection
> Optimize resources
> OpenDS specific
Use internal operations through JNDI or LDAP Java SDK
> Allows to code the operations for either internal OpenDS or external LDAP

                            LOGO SPEAKER‘S COMPANY

Pure LDAP connections
Example using JNDI:
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "ldap://localhost:10389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");

DirContext context = new InitialDirContext(env);
// Do whatever you want with the connection here

                        LOGO SPEAKER‘S COMPANY

The InternalClientConnection class provides methods for all LDAP operations
> You can get a root connection, or a connection authenticated as a given user
> Add, compare, delete, extended, modify, and modify DN are working as
> Searches can collect matching entries in a list or use a callback to provide
   entries as they're found
> Bind operations will work, i.e. check the credentials of the user, but won't change
   the identity associated with the connection
> Abandon and unbind aren't supported for internal operations and won't do

                              LOGO SPEAKER‘S COMPANY

InternalClientConnection example code
Import org.opends.server.protocols.internal.InternalClientConnection;
If no worry about authorization, do everything as “root”:
>   InternalClientConnection IConn =
Otherwise specify the authorization DN :
>   InternalClientConnection IConn = new InternalClientConnection(DN);
Then perform the operations:
>   InternalSearchOperation searchOperation =
    for (SearchResultEntry matchingEntry :
      // Do something with the entry.

                               LOGO SPEAKER‘S COMPANY

The Hybrid mode
Allow to code using JNDI or LDAP Java SDK
> Same code can work with both internal operations and external servers
But uses directly internalClientConnection through an InternalLDAPSocket
>   org.opends.server.protocols.internal.InternalLDAPSocket class
>   extends the superclass
A simple property change allows to select the OpenDS Embedded instance or an
external LDAPv3 compliant server

                            LOGO SPEAKER‘S COMPANY

JNDI & InternalLDAPSocket
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "ldap://doesntmatter:10389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");

DirContext context = new InitialDirContext(env);
// Do whatever you want with the connection here

                        LOGO SPEAKER‘S COMPANY

LDAP Java SDK & InternalLDAPSocket
Mozilla LDAP Java SDK uses its own LDAPSocketFactory which requires a single
makeSocket method
    public Socket makeSocket(String host, int port) {
        return new InternalLDAPSocket();
    LDAPConnection conn = new LDAPConnection(this);
    conn.connect(3, "doesntmatter", 10389,
        "cn=Directory Manager", "password");

    LDAPSearchResults results ="dc=example,dc=com",
                                     "(uid=john doe)", null, false);
    while (results.hasMoreElements()){
        LDAPEntry e =;
        System.out.println("Found matching entry "+ e.getDN() +".");

                           LOGO SPEAKER‘S COMPANY

Limitations to the InternalLDAPSocket
Using InternalLDAPSocket allows to make full use of the LDAP protocol
> SSL or TLS cannot be used, only cleartext communication
> SASL authentication cannot be used, only Simple authentication
> Abandon does nothing, there is currently no way to abandon internal operations

                            LOGO SPEAKER‘S COMPANY

Setting Up Replication
Replication allows to have multiple live copies of the stored data
Right now there is no programatic API to enable replication
Use the dsReplication CLI
    $ dsreplication enable –no-prompt
      --host1 host1 --port1 10389 --bindDN1 "cn=Directory Manager"
      --bindPassword1 password --replicationPort1 8989
      --host2 host2 --port2 10389 --bindDN2 "cn=Directory Manager"
      --bindPassword2 password --replicationPort2 8989
      --adminUID admin --adminPassword password
      --baseDN "dc=example,dc=com"

                              LOGO SPEAKER‘S COMPANY

Setting Replication from an Application
import org.opends.guitools.replicationcli.ReplicationCliMain;

String[] enableCmd= {
            "enable",                // 0
            "--no-prompt",           // 1
            "--host1",               // 2
            "host1val",              // 3
int ret = ReplicationCliMain.mainCLI( enableCmd,
            false /* don't initialize server */,
            System.out, System.err, null);

                        LOGO SPEAKER‘S COMPANY

OpenDS is a full LDAPv3 compliant server, 100% pure Java
It can be embedded in Java applications
> For a Better “Out of the Box” experience
> To run in the same JVM (web container)
It can be accessed by LDAP and/or by Internal Operations
> Utility class allows the same code to access both external and internal LDAP

More details can be found on the OpenDS Wiki:

Check OpenDS at

                            LOGO SPEAKER‘S COMPANY
Ludovic Poitou 

Sun Microsystems, Inc.

To top