From c1ebddb4a2d4e1dbd3a720cd9575446a9f322cf1 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 22 Feb 2013 11:27:11 +0000
Subject: [PATCH] Fix OPENDJ-757: Add Rest2LDAP gateway Servlet

---
 opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/package-info.java                       |   20 ++
 /dev/null                                                                                                                                |  118 -------------
 opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/WEB-INF/web.xml                                                              |   29 +++
 opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/opendj-rest2ldap-servlet.json                                                |   55 ++++++
 opendj-sdk/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java                                          |   46 +++-
 opendj-sdk/opendj3/pom.xml                                                                                                               |    3 
 opendj-sdk/opendj3/opendj-rest2ldap-servlet/pom.xml                                                                                      |  107 +++++++++++
 opendj-sdk/opendj3/opendj-rest2ldap/pom.xml                                                                                              |    4 
 opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/Rest2LDAPConnectionFactoryProvider.java |  143 +++++++++++++++
 9 files changed, 388 insertions(+), 137 deletions(-)

diff --git a/opendj-sdk/opendj3/opendj-rest2ldap-servlet/pom.xml b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/pom.xml
new file mode 100644
index 0000000..11c2ec8
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/pom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  The contents of this file are subject to the terms of the Common Development and
+  Distribution License (the License). You may not use this file except in compliance with the
+  License.
+
+  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+  specific language governing permission and limitations under the License.
+
+  When distributing Covered Software, include this CDDL Header Notice in each file and include
+  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+  Header, with the fields enclosed by brackets [] replaced by your own identifying
+  information: "Portions Copyright [year] [name of copyright owner]".
+
+  Copyright 2013 ForgeRock AS.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>opendj-project</artifactId>
+        <groupId>org.forgerock.opendj</groupId>
+        <version>3.0.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>opendj-rest2ldap-servlet</artifactId>
+    <name>OpenDJ Commons REST LDAP Gateway</name>
+    <description>
+        Provides integration between the OpenDJ Commons REST Adapter and Servlet APIs.
+    </description>
+    <packaging>bundle</packaging>
+    <properties>
+        <forgerockRestVersion>2.0.0-SNAPSHOT</forgerockRestVersion>
+        <jacksonVersion>1.9.2</jacksonVersion>
+        <checkstyleHeaderLocation>org/forgerock/checkstyle/default-java-header</checkstyleHeaderLocation>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.forgerock.opendj</groupId>
+            <artifactId>opendj-rest2ldap</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.forgerock.commons</groupId>
+            <artifactId>json-resource-servlet</artifactId>
+            <version>${forgerockRestVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <version>${jacksonVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>${jacksonVersion}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.forgerock.opendj.rest2ldap.servlet;version=${project.version}
+                        </Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>war</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>war</goal>
+                        </goals>
+                        <configuration>
+                            <classifier>servlet</classifier>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>8.1.7.v20120910</version>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/Rest2LDAPConnectionFactoryProvider.java b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/Rest2LDAPConnectionFactoryProvider.java
new file mode 100644
index 0000000..48c3419
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/Rest2LDAPConnectionFactoryProvider.java
@@ -0,0 +1,143 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development and
+ * Distribution License (the License). You may not use this file except in compliance with the
+ * License.
+ *
+ * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+ * specific language governing permission and limitations under the License.
+ *
+ * When distributing Covered Software, include this CDDL Header Notice in each file and include
+ * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+ * Header, with the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions copyright [year] [name of copyright owner]".
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.rest2ldap.servlet;
+
+import java.io.InputStream;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.forgerock.json.fluent.JsonValue;
+import org.forgerock.json.resource.CollectionResourceProvider;
+import org.forgerock.json.resource.ConnectionFactory;
+import org.forgerock.json.resource.Resources;
+import org.forgerock.json.resource.Router;
+import org.forgerock.opendj.rest2ldap.Rest2LDAP;
+import org.forgerock.opendj.rest2ldap.Rest2LDAP.Builder;
+
+/**
+ * The connection factory provider which is used by the OpenDJ Commons REST LDAP
+ * Gateway.
+ */
+public final class Rest2LDAPConnectionFactoryProvider {
+    private static final String INIT_PARAM_CONFIG_FILE = "config-file";
+
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
+    /**
+     * Returns a JSON resource connection factory configured using the
+     * configuration file named in the {@code config-file} Servlet
+     * initialization parameter. The configuration file should have the
+     * following JSON structure excluding the C-like comments:
+     *
+     * <pre>
+     * {
+     *     // The LDAP server configuration - see Rest2LDAP.configureConnectionFactory(JsonValue).
+     *     "primaryLDAPServers" : [
+     *         {
+     *             "hostname" : "host1.example.com",
+     *             "port"     : 389
+     *         }
+     *     ],
+     *
+     *     ...
+     *
+     *     // The LDAP mappings
+     *     "mappings" : {
+     *         "/users" : {
+     *             // The LDAP mapping for /users - Rest2LDAP.Builder.configureMapping(JsonValue).
+     *             "baseDN" : "ou=people,dc=example,dc=com",
+     *
+     *             ...
+     *         },
+     *         "/groups" : {
+     *             // The LDAP mapping for /groups - Rest2LDAP.Builder.configureMapping(JsonValue).
+     *             "baseDN" : "ou=groups,dc=example,dc=com",
+     *
+     *             ...
+     *         }
+     *     }
+     * }
+     * </pre>
+     *
+     * @param config
+     *            The Servlet configuration.
+     * @return The configured JSON resource connection factory.
+     * @throws ServletException
+     *             If the connection factory could not be initialized.
+     * @see Rest2LDAP#configureConnectionFactory(JsonValue)
+     * @see Builder#configureMapping(JsonValue)
+     */
+    public static ConnectionFactory getConnectionFactory(final ServletConfig config)
+            throws ServletException {
+        final String configFileName = config.getInitParameter(INIT_PARAM_CONFIG_FILE);
+        if (configFileName == null) {
+            throw new ServletException("Servlet initialization parameter '"
+                    + INIT_PARAM_CONFIG_FILE + "' not specified");
+        }
+        final InputStream configFile =
+                config.getServletContext().getResourceAsStream(configFileName);
+        if (configFile == null) {
+            throw new ServletException("Servlet configuration file '" + configFileName
+                    + "' not found");
+        }
+        try {
+            // Parse the config file.
+            final Object content = JSON_MAPPER.readValue(configFile, Object.class);
+            if (!(content instanceof Map)) {
+                throw new ServletException("Servlet configuration file '" + configFileName
+                        + "' does not contain a valid JSON configuration");
+            }
+            final JsonValue configuration = new JsonValue(content);
+
+            // Parse the LDAP connection configuration.
+            final org.forgerock.opendj.ldap.ConnectionFactory ldapFactory =
+                    Rest2LDAP.configureConnectionFactory(configuration);
+
+            // Create the router.
+            final Router router = new Router();
+            final JsonValue mappings = configuration.get("mappings").required();
+            for (final String mappingUrl : mappings.keys()) {
+                final JsonValue mapping = mappings.get(mappingUrl);
+                final CollectionResourceProvider provider =
+                        Rest2LDAP.builder().connectionFactory(ldapFactory)
+                                .configureMapping(mapping).build();
+                router.addRoute(mappingUrl, provider);
+            }
+            return Resources.newInternalConnectionFactory(router);
+        } catch (final ServletException e) {
+            // Rethrow.
+            throw e;
+        } catch (final Exception e) {
+            throw new ServletException("Servlet configuration file '" + configFileName
+                    + "' could not be read: " + e.getMessage());
+        } finally {
+            try {
+                configFile.close();
+            } catch (final Exception e) {
+                // Ignore.
+            }
+        }
+    }
+
+    // Prevent instantiation.
+    private Rest2LDAPConnectionFactoryProvider() {
+        // Nothing to do.
+    }
+
+}
diff --git a/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/package-info.java b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/package-info.java
new file mode 100644
index 0000000..53ce09f
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/java/org/forgerock/opendj/rest2ldap/servlet/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development and
+ * Distribution License (the License). You may not use this file except in compliance with the
+ * License.
+ *
+ * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+ * specific language governing permission and limitations under the License.
+ *
+ * When distributing Covered Software, include this CDDL Header Notice in each file and include
+ * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+ * Header, with the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions copyright [year] [name of copyright owner]".
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+
+/**
+ * Provides integration between the OpenDJ Commons REST Adapter and Servlet APIs.
+ */
+package org.forgerock.opendj.rest2ldap.servlet;
diff --git a/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/WEB-INF/web.xml b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..afc4e7f
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+    version="2.5">
+
+    <display-name>Json Resource Servlet</display-name>
+
+    <servlet>
+        <servlet-name>OpenDJ Commons REST LDAP Gateway</servlet-name>
+        <servlet-class>org.forgerock.json.resource.servlet.HttpServlet</servlet-class>
+
+        <init-param>
+            <param-name>connection-factory-class</param-name>
+            <param-value>org.forgerock.opendj.rest2ldap.servlet.Rest2LDAPConnectionFactoryProvider</param-value>
+        </init-param>
+
+        <init-param>
+            <param-name>config-file</param-name>
+            <param-value>/opendj-rest2ldap-servlet.json</param-value>
+        </init-param>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>OpenDJ Commons REST LDAP Gateway</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
+ 
\ No newline at end of file
diff --git a/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/opendj-rest2ldap-servlet.json b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/opendj-rest2ldap-servlet.json
new file mode 100644
index 0000000..3feda51
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-rest2ldap-servlet/src/main/webapp/opendj-rest2ldap-servlet.json
@@ -0,0 +1,55 @@
+{
+    "primaryLDAPServers" : [
+        {
+            "hostname" : "localhost",
+            "port"     : 1389
+        }
+    ],
+
+    "authentication" : {
+        "bindDN"   : "cn=directory manager",
+        "password" : "password"
+    },
+
+    "connectionPoolSize"       : 10,
+    "heartBeatIntervalSeconds" : 30,
+
+    "mappings" : {
+        "/users" : {
+            "baseDN" : "ou=people,dc=example,dc=com",
+            "readOnUpdatePolicy" : "controls",
+            "additionalLDAPAttributes" : [
+                {
+                    "type" : "objectClass",
+                    "values" : [
+                        "top",
+                        "person",
+                        "organizationalPerson",
+                        "inetOrgPerson"
+                    ]
+                }
+            ],
+            "namingStrategy" : {
+                "strategy" : "clientDNNaming",
+                "dnAttribute" : "uid"
+            },
+            "etagAttribute" : "etag",
+            "attributes" : {
+                "schemas"     : { "constant" : [ "urn:scim:schemas:core:1.0" ] },
+                "id"          : { "simple"   : { "ldapAttribute" : "uid", "isSingleValued" : true, "isRequired" : true, "writability" : "createOnly" } },
+                "rev"         : { "simple"   : { "ldapAttribute" : "etag", "isSingleValued" : true, "writability" : "readOnly" } },
+                "userName"    : { "simple"   : { "ldapAttribute" : "mail", "isSingleValued" : true, "writability" : "readOnly" } },
+                "displayName" : { "simple"   : { "ldapAttribute" : "cn", "isSingleValued" : true, "isRequired" : true } },
+                "name" : { "object"   : {
+                    "givenName"  : { "simple" : { "ldapAttribute" : "givenName", "isSingleValued" : true } },
+                    "familyName" : { "simple" : { "ldapAttribute" : "sn", "isSingleValued" : true, "isRequired" : true } }
+                } },
+                "contactInformation" : { "object"   : {
+                    "telephoneNumber" : { "simple" : { "ldapAttribute" : "telephoneNumber", "isSingleValued" : true } },
+                    "emailAddress"    : { "simple" : { "ldapAttribute" : "mail", "isSingleValued" : true } }
+                } }
+            }
+        }
+    }
+}
+
diff --git a/opendj-sdk/opendj3/opendj-rest2ldap/pom.xml b/opendj-sdk/opendj3/opendj-rest2ldap/pom.xml
index 2c5bde3..6c1fe89 100644
--- a/opendj-sdk/opendj3/opendj-rest2ldap/pom.xml
+++ b/opendj-sdk/opendj3/opendj-rest2ldap/pom.xml
@@ -23,9 +23,9 @@
         <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>opendj-rest2ldap</artifactId>
-    <name>OpenDJ REST to LDAP Gateway</name>
+    <name>OpenDJ Commons REST Adapter</name>
     <description>
-        This module includes APIs for implementing REST to LDAP gateways.
+        This module includes APIs for accessing LDAP repositories using commons REST.
     </description>
     <packaging>jar</packaging>
     <properties>
diff --git a/opendj-sdk/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java b/opendj-sdk/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
index 6ce5469..97826f5 100644
--- a/opendj-sdk/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
+++ b/opendj-sdk/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
@@ -47,6 +47,8 @@
 import org.forgerock.opendj.ldap.RDN;
 import org.forgerock.opendj.ldap.RoundRobinLoadBalancingAlgorithm;
 import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.requests.BindRequest;
+import org.forgerock.opendj.ldap.requests.Requests;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.forgerock.opendj.ldap.schema.Schema;
@@ -117,8 +119,7 @@
          * @throws IllegalArgumentException
          *             If the configuration is invalid.
          */
-        public Builder configureConnectionFactory(final JsonValue configuration)
-                throws IllegalArgumentException {
+        public Builder configureConnectionFactory(final JsonValue configuration) {
             connectionFactory(Rest2LDAP.configureConnectionFactory(configuration));
             return this;
         }
@@ -192,8 +193,7 @@
          * @throws IllegalArgumentException
          *             If the configuration is invalid.
          */
-        public Builder configureMapping(final JsonValue configuration)
-                throws IllegalArgumentException {
+        public Builder configureMapping(final JsonValue configuration) {
             baseDN(configuration.get("baseDN").required().asString());
 
             final JsonValue readOnUpdatePolicy = configuration.get("readOnUpdatePolicy");
@@ -545,9 +545,10 @@
      *         ...
      *     },
      *
-     *     // Authentication configuration (mandatory and TBD).
+     *     // Authentication configuration (optional and TBD).
      *     "authentication" : {
-     *         ...
+     *         "bindDN"   : "cn=directory manager",
+     *         "password" : "password"
      *     },
      * }
      * </pre>
@@ -558,32 +559,41 @@
      * @throws IllegalArgumentException
      *             If the configuration is invalid.
      */
-    public static ConnectionFactory configureConnectionFactory(final JsonValue configuration)
-            throws IllegalArgumentException {
+    public static ConnectionFactory configureConnectionFactory(final JsonValue configuration) {
         // Parse pool parameters,
         final int connectionPoolSize =
                 Math.max(configuration.get("connectionPoolSize").defaultTo(10).asInteger(), 1);
         final int heartBeatIntervalSeconds =
                 Math.max(configuration.get("heartBeatIntervalSeconds").defaultTo(30).asInteger(), 1);
 
+        // Parse authentication parameters.
+        final BindRequest bindRequest;
+        if (configuration.isDefined("authentication")) {
+            final JsonValue authn = configuration.get("authentication");
+            bindRequest =
+                    Requests.newSimpleBindRequest(authn.get("bindDN").required().asString(), authn
+                            .get("password").required().asString().toCharArray());
+        } else {
+            bindRequest = null;
+        }
+
         // Parse primary data center.
         final JsonValue primaryLDAPServers = configuration.get("primaryLDAPServers");
-        if (primaryLDAPServers == null || !primaryLDAPServers.isList()
-                || primaryLDAPServers.size() == 0) {
+        if (!primaryLDAPServers.isList() || primaryLDAPServers.size() == 0) {
             throw new IllegalArgumentException("No primaryLDAPServers");
         }
         final ConnectionFactory primary =
-                parseLDAPServers(primaryLDAPServers, connectionPoolSize, heartBeatIntervalSeconds);
+                parseLDAPServers(primaryLDAPServers, bindRequest, connectionPoolSize,
+                        heartBeatIntervalSeconds);
 
         // Parse secondary data center(s).
         final JsonValue secondaryLDAPServers = configuration.get("secondaryLDAPServers");
         final ConnectionFactory secondary;
-        if (secondaryLDAPServers != null && secondaryLDAPServers.isList()
-                && secondaryLDAPServers.size() != 0) {
+        if (secondaryLDAPServers.isList() && secondaryLDAPServers.size() != 0) {
             secondary =
-                    parseLDAPServers(secondaryLDAPServers, connectionPoolSize,
+                    parseLDAPServers(secondaryLDAPServers, bindRequest, connectionPoolSize,
                             heartBeatIntervalSeconds);
-        } else if (secondaryLDAPServers != null && !secondaryLDAPServers.isList()) {
+        } else if (!secondaryLDAPServers.isNull()) {
             throw new IllegalArgumentException("Invalid secondaryLDAPServers configuration");
         } else {
             secondary = null;
@@ -615,12 +625,16 @@
     }
 
     private static ConnectionFactory parseLDAPServers(final JsonValue config,
-            final int connectionPoolSize, final int heartBeatIntervalSeconds) {
+            final BindRequest bindRequest, final int connectionPoolSize,
+            final int heartBeatIntervalSeconds) {
         final List<ConnectionFactory> servers = new ArrayList<ConnectionFactory>(config.size());
         for (final JsonValue server : config) {
             final String host = server.get("hostname").required().asString();
             final int port = server.get("port").required().asInteger();
             ConnectionFactory factory = new LDAPConnectionFactory(host, port);
+            if (bindRequest != null) {
+                factory = Connections.newAuthenticatedConnectionFactory(factory, bindRequest);
+            }
             if (connectionPoolSize > 1) {
                 factory =
                         Connections.newHeartBeatConnectionFactory(factory,
diff --git a/opendj-sdk/opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/Example.java b/opendj-sdk/opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/Example.java
deleted file mode 100644
index 1dbbc4e..0000000
--- a/opendj-sdk/opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/Example.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * The contents of this file are subject to the terms of the Common Development and
- * Distribution License (the License). You may not use this file except in compliance with the
- * License.
- *
- * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
- * specific language governing permission and limitations under the License.
- *
- * When distributing Covered Software, include this CDDL Header Notice in each file and include
- * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
- * Header, with the fields enclosed by brackets [] replaced by your own identifying
- * information: "Portions Copyright [year] [name of copyright owner]".
- *
- * Copyright 2012-2013 ForgeRock AS.
- */
-
-package org.forgerock.opendj.rest2ldap;
-
-import static org.forgerock.json.resource.Resources.newInternalConnectionFactory;
-import static org.forgerock.opendj.ldap.Connections.newAuthenticatedConnectionFactory;
-import static org.forgerock.opendj.rest2ldap.Rest2LDAP.builder;
-import static org.forgerock.opendj.rest2ldap.Rest2LDAP.constant;
-import static org.forgerock.opendj.rest2ldap.Rest2LDAP.object;
-import static org.forgerock.opendj.rest2ldap.Rest2LDAP.simple;
-import static org.forgerock.opendj.rest2ldap.WritabilityPolicy.CREATE_ONLY;
-import static org.forgerock.opendj.rest2ldap.WritabilityPolicy.READ_ONLY;
-
-import java.util.Arrays;
-import java.util.logging.Logger;
-
-import org.forgerock.json.resource.CollectionResourceProvider;
-import org.forgerock.json.resource.Router;
-import org.forgerock.json.resource.servlet.HttpServlet;
-import org.forgerock.opendj.ldap.ConnectionFactory;
-import org.forgerock.opendj.ldap.LDAPConnectionFactory;
-import org.forgerock.opendj.ldap.requests.Requests;
-import org.glassfish.grizzly.http.server.HttpServer;
-import org.glassfish.grizzly.servlet.ServletRegistration;
-import org.glassfish.grizzly.servlet.WebappContext;
-
-/**
- * Example.
- */
-public class Example {
-
-    private static final Logger LOGGER = Logger.getLogger(Example.class.getName());
-    private static final int PORT = 18890;
-
-    /**
-     * REST 2 LDAP example application.
-     *
-     * @param args
-     *            Command line arguments.
-     * @throws Exception
-     *             If an unexpected error occurred.
-     */
-    public static void main(final String[] args) throws Exception {
-        // All LDAP resources will use this connection factory.
-        final ConnectionFactory ldapFactory =
-                newAuthenticatedConnectionFactory(new LDAPConnectionFactory("localhost", 1389),
-                        Requests.newSimpleBindRequest("cn=directory manager", "password"
-                                .toCharArray()));
-
-        // Create the router.
-        final Router router = new Router();
-
-        // Create user resource.
-        CollectionResourceProvider users =
-                builder().connectionFactory(ldapFactory).baseDN("ou=people,dc=example,dc=com")
-                    .mapper(object()
-                            .attribute("schemas", constant(Arrays.asList("urn:scim:schemas:core:1.0")))
-                            .attribute("id", simple("uid").isSingleValued().isRequired().writability(CREATE_ONLY))
-                            .attribute("rev", simple("etag").isSingleValued().writability(READ_ONLY))
-                            .attribute("userName", simple("mail").isSingleValued().writability(READ_ONLY))
-                            .attribute("displayName", simple("cn").isSingleValued().isRequired())
-                            .attribute("name", object()
-                                    .attribute("givenName", simple("givenName").isSingleValued())
-                                    .attribute("familyName", simple("sn").isSingleValued().isRequired()))
-                            .attribute("contactInformation", object()
-                                    .attribute("telephoneNumber", simple("telephoneNumber").isSingleValued())
-                                    .attribute("emailAddress", simple("mail").isSingleValued())))
-                    .additionalLDAPAttribute("objectClass", "top", "person", "organizationalPerson", "inetOrgPerson")
-                    .build();
-        router.addRoute("/users", users);
-
-        // Create group resource.
-        CollectionResourceProvider groups =
-                builder().connectionFactory(ldapFactory).baseDN("ou=groups,dc=example,dc=com")
-                    .mapper(object()
-                            .attribute("cn", simple("cn").isSingleValued())
-                            .attribute("description", simple("description"))
-                            .attribute("member", simple("uniquemember")))
-                    .build();
-        router.addRoute("/groups", groups);
-
-        final org.forgerock.json.resource.ConnectionFactory resourceFactory =
-                newInternalConnectionFactory(router);
-        final HttpServer httpServer = HttpServer.createSimpleServer("./", PORT);
-        try {
-            final WebappContext ctx = new WebappContext("example", "/example");
-            final ServletRegistration reg =
-                    ctx.addServlet("managed", new HttpServlet(resourceFactory));
-            reg.addMapping("/managed/*");
-            ctx.deploy(httpServer);
-
-            LOGGER.info("Starting server...");
-            httpServer.start();
-            LOGGER.info("Server started");
-            LOGGER.info("Press any key to stop the server...");
-            System.in.read();
-        } finally {
-            LOGGER.info("Stopping server...");
-            httpServer.stop();
-            LOGGER.info("Server stopped");
-        }
-    }
-
-}
diff --git a/opendj-sdk/opendj3/pom.xml b/opendj-sdk/opendj3/pom.xml
index 5c6b33b..0b4a369 100644
--- a/opendj-sdk/opendj3/pom.xml
+++ b/opendj-sdk/opendj3/pom.xml
@@ -91,8 +91,9 @@
   <modules>
     <module>opendj-ldap-sdk</module>
     <module>opendj-ldap-toolkit</module>
-    <module>opendj-rest2ldap</module>
     <module>opendj-ldap-sdk-examples</module>
+    <module>opendj-rest2ldap</module>
+    <module>opendj-rest2ldap-servlet</module>
     <module>opendj-server2x-adapter</module>
   </modules>
   <properties>

--
Gitblit v1.10.0