From 1f468b81913675dac6e0a2d984e63f66659e440e Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 25 Mar 2013 11:58:10 +0000
Subject: [PATCH] OPENDJ-808 Implement a simple commons REST based HTTP connection handler
---
opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java | 136 ++++++++++++++++++++++++--------------------
1 files changed, 74 insertions(+), 62 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java
index 8c32c84..4dfaff1 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java
@@ -31,6 +31,7 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
+import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
@@ -44,6 +45,8 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
@@ -51,10 +54,18 @@
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.codehaus.jackson.JsonParser;
+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.json.resource.servlet.HttpServlet;
+import org.forgerock.opendj.rest2ldap.AuthorizationPolicy;
+import org.forgerock.opendj.rest2ldap.Rest2LDAP;
+import org.forgerock.opendj.rest2ldap.servlet.Rest2LDAPContextFactory;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.http.server.ServerConfiguration;
@@ -63,6 +74,7 @@
import org.glassfish.grizzly.servlet.ServletRegistration;
import org.glassfish.grizzly.servlet.WebappContext;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
+import org.glassfish.grizzly.strategies.SameThreadIOStrategy;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.ConnectionHandlerCfg;
@@ -98,23 +110,6 @@
ServerShutdownListener, AlertGenerator
{
- /**
- * Fake Servlet.
- * <p>
- * TODO JNR remove when using REST2LDAP servlet
- */
- private static final class FakeServlet extends HttpServlet
- {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException
- {
- // TODO Auto-generated method stub
- super.doGet(req, resp);
- }
-
- }
-
/** The tracer object for the debug logger. */
private static final DebugTracer TRACER = getTracer();
@@ -124,6 +119,9 @@
/** SSL instance name used in context creation. */
private static final String SSL_CONTEXT_INSTANCE_NAME = "TLS";
+ private static final ObjectMapper JSON_MAPPER = new ObjectMapper().configure(
+ JsonParser.Feature.ALLOW_COMMENTS, true);
+
/** The initialization configuration. */
private HTTPConnectionHandlerCfg initConfig;
@@ -333,6 +331,16 @@
return clientConnections.keySet();
}
+ /**
+ * Gives access to the clientConnections to classes in this package.
+ *
+ * @return the Map containing the current client connections
+ */
+ Map<ClientConnection, ClientConnection> getClientConnectionsMap()
+ {
+ return clientConnections;
+ }
+
/** {@inheritDoc} */
@Override
public DN getComponentEntryDN()
@@ -660,35 +668,9 @@
private void startHttpServer()
{
- // TODO JNR stop Grizzly own logging.
- // [testng] Mar 14, 2013 11:22:13 AM org.glassfish.grizzly.http.server.
- // NetworkListener stop
- // [testng] INFO: Stopped listener bound to [0.0.0.0:8080]
- // [testng] Mar 14, 2013 11:22:19 AM org.glassfish.grizzly.servlet.
- // WebappContext deploy
- // [testng] INFO: Starting application [example] ...
- // [testng] Mar 14, 2013 11:22:19 AM org.glassfish.grizzly.servlet.
- // WebappContext initServlets
- // [testng] INFO: [example] Servlet
- // [org.opends.server.protocols.http.HTTPConnec
- // tionHandler$FakeServlet] registered for url pattern(s) [[/managed/*]].
- // [testng] Mar 14, 2013 11:22:19 AM
- // org.glassfish.grizzly.servlet.WebappContext
- // initFilters
- // [testng] INFO: [example] Filter [org.opends.server.protocols.http.
- // AllowAdressesFilter] registered for
- // url pattern(s) [[/managed/*]] and servlet name(s) [[]]
- // [testng] Mar 14, 2013 11:22:19 AM
- // org.glassfish.grizzly.servlet.WebappContext
- // deploy
- // [testng] INFO: Application [example] is ready to service requests. Root:
- // [/example].
- // [testng] Mar 14, 2013 11:22:19 AM org.glassfish.grizzly.http.server.
- // NetworkListener start
- // [testng] INFO: Started listener bound to [0.0.0.0:8080]
- // [testng] Mar 14, 2013 11:22:19 AM org.glassfish.grizzly.http.server.
- // HttpServer start
- // [testng] INFO: [HttpServer-1] Started.
+ // silence Grizzly's own logging
+ Logger.getLogger("org.glassfish.grizzly").setLevel(Level.OFF);
+
this.httpServer =
HttpServer.createSimpleServer("./", initConfig.getListenPort());
@@ -713,8 +695,11 @@
transport.setReadBufferSize(bufferSize);
transport.setWriteBufferSize(bufferSize);
// TODO JNR
- // transport.setIOStrategy(SameThreadIOStrategy.getInstance());
- // transport.setWorkerThreadPool(threadPool);
+ transport.setIOStrategy(SameThreadIOStrategy.getInstance());
+ // ThreadPoolConfig workerPoolConfig =
+ // ThreadPoolConfig.defaultConfig().copy();
+ // workerPoolConfig.setCorePoolSize(currentConfig
+ // .getNumRequestHandlers());
// transport.setWorkerThreadPoolConfig(workerPoolConfig);
transport.setServerConnectionBackLog(currentConfig.getAcceptBacklog());
@@ -725,17 +710,11 @@
}
}
- // TODO JNR what to use here?
- final String displayName = "example";
- final String contextPath = "/example";
- final String servletName = "managed";
- final String urlPattern = "/managed/*";
+ final String servletName = "OpenDJ Rest2LDAP servlet";
+ final String urlPattern = "/*";
+ final WebappContext ctx = new WebappContext(servletName);
- // TODO JNR what to use here?
- final WebappContext ctx = new WebappContext(displayName, contextPath);
-
- Filter filter =
- new CollectClientConnectionsFilter(this, clientConnections);
+ Filter filter = new CollectClientConnectionsFilter(this);
FilterRegistration filterReg =
ctx.addFilter("collectClientConnections", filter);
// TODO JNR this is not working
@@ -744,8 +723,14 @@
filterReg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST),
urlPattern);
+ ConnectionFactory connFactory =
+ getConnectionFactory(getFileForPath(this.currentConfig
+ .getConfigFile()));
+
final ServletRegistration reg =
- ctx.addServlet(servletName, new FakeServlet());
+ ctx.addServlet(servletName, new HttpServlet(connFactory,
+ // Used for hooking our HTTPClientConnection in Rest2LDAP
+ Rest2LDAPContextFactory.getHttpServletContextFactory()));
reg.addMapping(urlPattern);
ctx.deploy(this.httpServer);
@@ -772,6 +757,33 @@
}
}
+ private ConnectionFactory getConnectionFactory(File configFile)
+ throws Exception
+ {
+ // Parse the config file.
+ final Object content = JSON_MAPPER.readValue(configFile, Object.class);
+ if (!(content instanceof Map))
+ {
+ throw new ServletException("Servlet configuration file '" + configFile
+ + "' does not contain a valid JSON configuration");
+ }
+ final JsonValue configuration = new JsonValue(content);
+
+ // Create the router.
+ final Router router = new Router();
+ final JsonValue mappings =
+ configuration.get("servlet").get("mappings").required();
+ for (final String mappingUrl : mappings.keys())
+ {
+ final JsonValue mapping = mappings.get(mappingUrl);
+ final CollectionResourceProvider provider =
+ Rest2LDAP.builder().authorizationPolicy(AuthorizationPolicy.REUSE)
+ .configureMapping(mapping).build();
+ router.addRoute(mappingUrl, provider);
+ }
+ return Resources.newInternalConnectionFactory(router);
+ }
+
private void stopHttpServer()
{
TRACER.debugInfo("Stopping HTTP server...");
--
Gitblit v1.10.0