OpenDS Inside

Download OpenDS

This entry explains a simple example of OpenDS, the pure Java LDAP directory server, embedded in a web application. Ludovic Poitou presented on the subject at a talk he gave at Jazoon in Zurich this summer.

Based on those ideas I wrote a sample servlet, leaning as much as I could on NetBeans 6.1 to handle the build management and deployment in GlassFish. The servlet code is posted at the bottom of this entry.

Before You Start

If you want to try this yourself, get NetBeans with an application server plugin and an application server to manage such as GlassFish or Tomcat. Otherwise you will have to do the work of writing an ant build script or a Makefile. (See Tools > Plugins and Tools > Servers in NetBeans 6.1 for example.)

Also download and install OpenDS, importing some people entries. (The servlet uses CN and SN in the search filter.) You will embed the result in your application. OpenDS databases and other files are completely portable, so you can set up your test instance in one place, and copy the files to a completely different system.

To Create the Web App

  1. In NetBeans, select File > New Project.

  2. In the New Project wizard, Categories: Web > Projects : Web Application.

    Give your project a name such as OpenDSInsideSample.

    For the other settings, accept the defaults, assuming you configured your Web Application server before you started.

To Add the Servlet

  1. Right-click the project Source Packages > New > Java Class...

  2. In the Name and Location page of the wizard, Class Name: OpenDSServlet, Package: org.opendsinside.embedded.

    For other settings, accept the defaults.

  3. Replace the content of the file with the code for OpenDSServlet, shown below.

    Note NetBeans shows lots of red-colored errors in the code at this point. That's because you have not yet added the OpenDS .jar files. So NetBeans cannot resolve many of the missing class names, yet.

To Add the Home Page

  1. Under Web Pages, delete the existing index.jsp file.

  2. Right-click Web Pages > New > HTML..., and then create an empty index.html file using the wizard.

  3. Replace the content with the content of index.html, shown below.

To Add OpenDS Inside

  1. Using a terminal, or a file manager, copy the OpenDS configuration, databases, .jars (lib/), locks, and logs to the WEB-INF folder where NetBeans stores your project.

    When you finish, your files should appear in the NetBeans Projects view.

  2. Right-click Libraries > Add JAR/Folder..., and add the OpenDS.jar, je.jar, quicksetup.jar, and aspectjrt.jar files you copied to WEB-INF/lib/.

    As a result, the errors in OpenDSServlet should disappear as NetBeans resolves the class references for OpenDS objects.

  3. Right-click the project, and then select Run.

    After the web application starts and is deployed, you can access it through your browser at http://host:port/OpenDSServlet.

    Notice that the LDIF contains even userPassword, because the servlet gets a root (Directory Manager) connection. In a real-world version, you would get more than one connection, and you would no doubt also use access control.

For details and further information, see the OpenDS Wiki articles on embedding OpenDS.


Here is the web page, index.html.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Redirecting to OpenDS Embedded Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="refresh" content="0;./OpenDSServlet">
  </head>
  <body  bgcolor='#a3b8cb'>
      <p>This page redirects to the web app after starting OpenDS...</p>
  </body>
</html>

Here is the servlet code, OpenDSServlet.java.

package org.opendsinside.embedded;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.opends.server.config.ConfigException;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.types.DirectoryEnvironmentConfig;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchScope;
import org.opends.server.util.EmbeddedUtils;

/\*
 \* Search an embedded OpenDS instance by using a web form.
 \*/
public class OpenDSServlet extends HttpServlet {

    private InternalClientConnection InternalConnection;

    /\*\*
     \* When the servlet starts, configure OpenDS, start OpenDS,
     \* and open an internal connection to OpenDS.
     \*/
    @Override
    public void init(ServletConfig config) throws ServletException {
        // Ensure that OpenDS gets configured.
        ServletContext context = config.getServletContext();
        String appRoot = context.getRealPath(context.getContextPath());

        DirectoryEnvironmentConfig envConfig = new DirectoryEnvironmentConfig();
        try {
            envConfig.setServerRoot(new File(appRoot + "/WEB-INF"));
            envConfig.setConfigFile(new File(appRoot +
                    "/WEB-INF/config/config.ldif"));
            envConfig.setDisableConnectionHandlers(true);

        // If something goes wrong configuring the server, log what happened.
        } catch (InitializationException ex) {
            Logger.getLogger(OpenDSServlet.class.getName())
                    .log(Level.SEVERE, null, ex);
            ex.printStackTrace();
            throw new ServletException(
                    "Failed to setup server config: " +
                    envConfig.getConfigFile().getName());
        }

        // Start the OpenDS server.
        if (EmbeddedUtils.isRunning()) {
            return;
        } else {
            try {
                EmbeddedUtils.startServer(envConfig);

            // If omething went wrong starting the server, log what happened.
            } catch (ConfigException ex) {
                Logger.getLogger(OpenDSServlet.class.getName())
                        .log(Level.SEVERE, null, ex);
                ex.printStackTrace();
                throw new ServletException(
                        "Failed to start server: config exception.");
            } catch (InitializationException ex) {
                Logger.getLogger(OpenDSServlet.class.getName())
                        .log(Level.SEVERE, null, ex);
                ex.printStackTrace();
                throw new ServletException(
                        "Failed to start server: initialization exception.");
            }
        }

        // Get an internal, root connection to the OpenDS instance.
        InternalConnection = InternalClientConnection.getRootConnection();
        if (InternalConnection == null) {
            throw new ServletException("Internal connection is null.");
        }
    }

    /\*\*
     \* Generate the web form and results of searching OpenDS.
     \*/
    protected void processRequest(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {

        // Get the name to search for
        String name = request.getParameter("SrchStr");
        if (name == null) { // No search string when the page is first loaded.
            name = "";
        }

        // Send back an HTML page in response
        String OpenDSLogo =
          "<a href='https://opends.dev.java.net/public/downloads_index.html'>" +
          "<img src='https://opends.dev.java.net/public/images/opends_logo.png' " +
          "alt='Download OpenDS' style='float: right;' border='0' width='155'" +
          "height='49'></a>";

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Embedded OpenDS Example</title>");
            out.println("</head>");
            out.println("<body bgcolor='#a3b8cb'>");
            out.println(OpenDSLogo);

            out.println("<h2>Embedded OpenDS Example</h2>");
            out.println("<p>This web app embeds an instance of OpenDS, ");
            out.println("the pure Java LDAP Directory Server.</p><hr />");

            out.println("<h2>NameLookupTool 0.0.001</h2>");
            out.println("<form>");
            out.println("Enter a name: <input type='text' name='SrchStr' ");
            out.println("value='"+name+"'/><input type='submit' value='OK'/>");
            out.println("</form>");

            out.println(getSearchResult(name));

            out.println("</body>");
            out.println("</html>");
        } finally {
            out.close();
        }
    }

    /\*\*
     \* Return an HTML snippet containing LDIF for entries found.
     \* @param name Used to construct filter "(|(cn=\*name\*)(sn=\*name\*))"
     \*/
    String getSearchResult(String name) {
        String result = "";

        // No results without a "name" string to search for
        if (name == null || name.equals("")) {
            return result;
        }

        // Get LDIF for entries whose common name or surname contains "name"
        InternalSearchOperation searchOperation;
        try {
            searchOperation = InternalConnection.processSearch(
                    "dc=example,dc=com",
                    SearchScope.WHOLE_SUBTREE,
                    "(|(cn=\*" + name + "\*)(sn=\*" + name + "\*))");
            for (SearchResultEntry matchingEntry :
                    searchOperation.getSearchEntries()) {
                result += matchingEntry.toLDIFString() + "\\n";
            }
        } catch (DirectoryException ex) {
            Logger.getLogger(OpenDSServlet.class.getName())
                    .log(Level.SEVERE, null, ex);
        }

        // Return the HTML snippet, depending on whether the search
        // found any directory entries.
        if (!result.equals("")) {
            return "<hr /><h2>Entries Found</h2><pre>" + result + "</pre>";
        } else {
            return "<hr /><p>No results found searching for " + name + ".</p>";
        }
    }

    /\*\*
     \* Stop the OpenDS instance when the servlet is shut down.
     \*/
    public void destroy(ServletContext context) {
        EmbeddedUtils.stopServer("org.mcraig.hello.OpenDSServlet", null);
    }

    /\*\*
     \* Handles the HTTP <code>GET</code> method.
     \* @param request servlet request
     \* @param response servlet response
     \*/
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /\*\*
     \* Handles the HTTP <code>POST</code> method.
     \* @param request servlet request
     \* @param response servlet response
     \*/
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /\*\*
     \* Returns a short description of the servlet.
     \*/
    public String getServletInfo() {
        return "Short description";
    }
}
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Mark Craig writes about Directory Services products and technologies. The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today