mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Gaetan Boismal
25.12.2015 dd54ba6d6bda279039e5cbd020ebdcf101a5b89c
OPENDJ-1666 Code cleanup

* org.opends.server.protocols.http.HttpConnectionHandler
** Fix copyright section
** Make code more readable
*** Reformat
*** Inline some local variables

* org.opends.server.protocols.http.HTTPClientConnection
** Fix copyright section
** Reformat

* org.opends.server.protocols.http.CollectClientConnectionsFilter
** Fix copyright

* org.opends.server.protocols.http.CollectClientConnectionsFilterTest
** Reformat
4 files modified
413 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/protocols/http/CollectClientConnectionsFilter.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPClientConnection.java 102 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPConnectionHandler.java 252 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/protocols/http/CollectClientConnectionsFilterTest.java 57 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/protocols/http/CollectClientConnectionsFilter.java
@@ -21,7 +21,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2013-2015 ForgeRock AS
 *      Copyright 2013-2015 ForgeRock AS
 */
package org.opends.server.protocols.http;
opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPClientConnection.java
@@ -21,7 +21,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2013-2015 ForgeRock AS
 *      Copyright 2013-2015 ForgeRock AS
 */
package org.opends.server.protocols.http;
@@ -89,12 +89,10 @@
 * connection that will be accepted by an instance of the HTTP connection
 * handler.
 */
final class HTTPClientConnection extends ClientConnection implements
    HTTPRequestInfo
final class HTTPClientConnection extends ClientConnection implements HTTPRequestInfo
{
  // TODO JNR Confirm with Matt that persistent searches are inapplicable to
  // Rest2LDAP.
  // TODO JNR Confirm with Matt that persistent searches are inapplicable to Rest2LDAP.
  // TODO JNR Should I override getIdleTime()?
  /**
@@ -126,8 +124,8 @@
    final SearchResultHandler entryHandler;
    public SearchOperationWithPromise(Operation operation, LdapPromiseImpl<Result> promise,
        SearchResultHandler entryHandler)
    public SearchOperationWithPromise(
        Operation operation, LdapPromiseImpl<Result> promise, SearchResultHandler entryHandler)
    {
      super(operation, promise);
      this.entryHandler = entryHandler;
@@ -141,8 +139,7 @@
   * Official servlet property giving access to the SSF (Security Strength
   * Factor) used to encrypt the current connection.
   */
  private static final String SERVLET_SSF_CONSTANT =
      "javax.servlet.request.key_size";
  private static final String SERVLET_SSF_CONSTANT = "javax.servlet.request.key_size";
  /**
   * Indicates whether the Directory Server believes this connection to be valid
@@ -250,13 +247,11 @@
   * @param request
   *          represents this client connection.
   */
  public HTTPClientConnection(HTTPConnectionHandler connectionHandler,
      HttpServletRequest request)
  public HTTPClientConnection(HTTPConnectionHandler connectionHandler, HttpServletRequest request)
  {
    this.connectionHandler = connectionHandler;
    // memoize all the fields we need from the request before Grizzly decides to
    // recycle it
    // Memorize all the fields we need from the request before Grizzly decides to recycle it
    this.clientAddress = request.getRemoteAddr();
    this.clientPort = request.getRemotePort();
    this.serverAddress = request.getLocalAddr();
@@ -264,8 +259,7 @@
    this.remoteAddress = toInetAddress(request.getRemoteAddr());
    this.localAddress = toInetAddress(request.getLocalAddr());
    this.isSecure = request.isSecure();
    this.securityStrengthFactor =
        calcSSF(request.getAttribute(SERVLET_SSF_CONSTANT));
    this.securityStrengthFactor = calcSSF(request.getAttribute(SERVLET_SSF_CONSTANT));
    this.method = request.getMethod();
    this.query = computeQuery(request);
    this.protocol = request.getProtocol();
@@ -292,105 +286,90 @@
    return request.getRequestURI();
  }
  /** {@inheritDoc} */
  @Override
  public String getAuthUser()
  {
    return this.authUser;
  }
  /** {@inheritDoc} */
  @Override
  public long getConnectionID()
  {
    return connectionID;
  }
  /** {@inheritDoc} */
  @Override
  public HTTPConnectionHandler getConnectionHandler()
  {
    return connectionHandler;
  }
  /** {@inheritDoc} */
  @Override
  public long getTotalProcessingTime()
  {
    return totalProcessingTime.get();
  }
  /** {@inheritDoc} */
  @Override
  public String getProtocol()
  {
    return protocol;
  }
  /** {@inheritDoc} */
  @Override
  public String getClientAddress()
  {
    return clientAddress;
  }
  /** {@inheritDoc} */
  @Override
  public String getClientHost()
  {
    return clientHost;
  }
  /** {@inheritDoc} */
  @Override
  public int getClientPort()
  {
    return clientPort;
  }
  /** {@inheritDoc} */
  @Override
  public String getServerAddress()
  {
    return serverAddress;
  }
  /** {@inheritDoc} */
  @Override
  public String getServerHost()
  {
    return serverHost;
  }
  /** {@inheritDoc} */
  @Override
  public int getServerPort()
  {
    return serverPort;
  }
  /** {@inheritDoc} */
  @Override
  public InetAddress getRemoteAddress()
  {
    return remoteAddress;
  }
  /** {@inheritDoc} */
  @Override
  public InetAddress getLocalAddress()
  {
    return localAddress;
  }
  /** {@inheritDoc} */
  @Override
  public boolean isSecure()
  {
    return isSecure;
  }
  /** {@inheritDoc} */
  @Override
  public void sendResponse(Operation operation)
  {
@@ -400,8 +379,7 @@
    if (keepStats)
    {
      this.statTracker.updateRequestMonitoringData(getMethod(), time);
      this.statTracker.updateOperationMonitoringData(operation
          .getOperationType(), time);
      this.statTracker.updateOperationMonitoringData(operation.getOperationType(), time);
    }
    OperationWithPromise op = this.operationsInProgress.get(operation.getMessageID());
@@ -413,8 +391,8 @@
        if (keepStats)
        {
          this.statTracker.updateMessageWritten(new LDAPMessage(operation
              .getMessageID(), toResponseProtocolOp(operation)));
          this.statTracker.updateMessageWritten(
              new LDAPMessage(operation.getMessageID(), toResponseProtocolOp(operation)));
        }
      }
      catch (LdapException e)
@@ -471,10 +449,8 @@
    throw new RuntimeException("Not implemented for operation " + operation);
  }
  /** {@inheritDoc} */
  @Override
  public void sendSearchEntry(SearchOperation operation,
      SearchResultEntry searchEntry) throws DirectoryException
  public void sendSearchEntry(SearchOperation operation, SearchResultEntry searchEntry) throws DirectoryException
  {
    SearchOperationWithPromise op =
        (SearchOperationWithPromise) this.operationsInProgress.get(operation.getMessageID());
@@ -483,16 +459,15 @@
      op.entryHandler.handleEntry(from(searchEntry));
      if (keepStats)
      {
        this.statTracker.updateMessageWritten(new LDAPMessage(operation
            .getMessageID(), new SearchResultEntryProtocolOp(searchEntry)));
        this.statTracker.updateMessageWritten(
            new LDAPMessage(operation.getMessageID(), new SearchResultEntryProtocolOp(searchEntry)));
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean sendSearchReference(SearchOperation operation,
      SearchResultReference searchReference) throws DirectoryException
  public boolean sendSearchReference(SearchOperation operation, SearchResultReference searchReference)
      throws DirectoryException
  {
    SearchOperationWithPromise op =
        (SearchOperationWithPromise) this.operationsInProgress.get(operation.getMessageID());
@@ -501,18 +476,16 @@
      op.entryHandler.handleReference(from(searchReference));
      if (keepStats)
      {
        this.statTracker.updateMessageWritten(new LDAPMessage(operation.getMessageID(),
            new SearchResultReferenceProtocolOp(searchReference)));
        this.statTracker.updateMessageWritten(
            new LDAPMessage(operation.getMessageID(), new SearchResultReferenceProtocolOp(searchReference)));
      }
    }
    return connectionValid;
  }
  /** {@inheritDoc} */
  @Override
  protected boolean sendIntermediateResponseMessage(
      IntermediateResponse intermediateResponse)
  protected boolean sendIntermediateResponseMessage(IntermediateResponse intermediateResponse)
  {
    // if (keepStats)
    // {
@@ -523,7 +496,6 @@
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public void setAuthUser(String authUser)
  {
@@ -537,16 +509,14 @@
   *          not used with HTTP.
   */
  @Override
  public void disconnect(DisconnectReason disconnectReason,
      boolean sendNotification, LocalizableMessage message)
  public void disconnect(DisconnectReason disconnectReason, boolean sendNotification, LocalizableMessage message)
  {
    // Set a flag indicating that the connection is being terminated so
    // that no new requests will be accepted. Also cancel all operations
    // in progress.
    // that no new requests will be accepted.
    // Also cancel all operations in progress.
    synchronized (opsInProgressLock)
    {
      // If we are already in the middle of a disconnect, then don't
      // do anything.
      // If we are already in the middle of a disconnect, then don't do anything.
      if (disconnectRequested)
      {
        return;
@@ -578,8 +548,7 @@
    }
    else
    {
      cancelAllOperations(new CancelRequest(true, disconnectReason
          .getClosureMessage()));
      cancelAllOperations(new CancelRequest(true, disconnectReason.getClosureMessage()));
    }
    finalizeConnectionInternal();
@@ -588,35 +557,30 @@
    logDisconnect(this, disconnectReason, message);
  }
  /** {@inheritDoc} */
  @Override
  public String getMethod()
  {
    return this.method;
  }
  /** {@inheritDoc} */
  @Override
  public String getQuery()
  {
    return this.query;
  }
  /** {@inheritDoc} */
  @Override
  public int getStatusCode()
  {
    return this.statusCode.get();
  }
  /** {@inheritDoc} */
  @Override
  public String getUserAgent()
  {
    return this.userAgent;
  }
  /** {@inheritDoc} */
  @Override
  public Collection<Operation> getOperationsInProgress()
  {
@@ -629,7 +593,6 @@
    return results;
  }
  /** {@inheritDoc} */
  @Override
  public Operation getOperationInProgress(int messageID)
  {
@@ -682,7 +645,6 @@
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean removeOperationInProgress(int messageID)
  {
@@ -702,7 +664,6 @@
    return previousValue != null;
  }
  /** {@inheritDoc} */
  @Override
  public CancelResult cancelOperation(int messageID, CancelRequest cancelRequest)
  {
@@ -736,7 +697,6 @@
    return 0;
  }
  /** {@inheritDoc} */
  @Override
  public void cancelAllOperations(CancelRequest cancelRequest)
  {
@@ -757,7 +717,7 @@
            }
          }
          catch (Exception e)
          { // make sure all operations are cancelled, no matter what
          { // Make sure all operations are cancelled, no matter what
            logger.traceException(e);
          }
        }
@@ -771,7 +731,6 @@
    }
  }
  /** {@inheritDoc} */
  @Override
  public void cancelAllOperationsExcept(CancelRequest cancelRequest,
      int messageID)
@@ -790,14 +749,12 @@
    }
  }
  /** {@inheritDoc} */
  @Override
  public long getNumberOfOperations()
  {
    return this.operationsPerformed.get();
  }
  /** {@inheritDoc} */
  @Override
  public String getMonitorSummary()
  {
@@ -835,7 +792,6 @@
    }
  }
  /** {@inheritDoc} */
  @Override
  public void toString(StringBuilder buffer)
  {
@@ -855,33 +811,29 @@
    return statTracker;
  }
  /** {@inheritDoc} */
  @Override
  public int getSSF()
  {
    return securityStrengthFactor;
  }
  /** {@inheritDoc} */
  @Override
  public boolean isConnectionValid()
  {
    return connectionValid;
  }
  /** {@inheritDoc} */
  @Override
  public boolean isInnerConnection()
  {
    return true;
  }
  /** {@inheritDoc} */
  @Override
  public void log(int statusCode)
  {
    if (this.statusCode.compareAndSet(0, statusCode))
    { // this request was not logged before
    { // This request was not logged before
      HTTPAccessLogger.logRequestInfo(this);
    }
  }
opendj-server-legacy/src/main/java/org/opends/server/protocols/http/HTTPConnectionHandler.java
@@ -21,8 +21,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2013-2015 ForgeRock AS
 *      Portions Copyright 2014 ForgeRock AS
 *      Copyright 2013-2015 ForgeRock AS
 */
package org.opends.server.protocols.http;
@@ -68,7 +67,6 @@
import org.forgerock.opendj.rest2ldap.servlet.Rest2LDAPContextFactory;
import org.glassfish.grizzly.http.HttpProbe;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.HttpServerMonitoringConfig;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.http.server.ServerConfiguration;
import org.glassfish.grizzly.monitoring.MonitoringConfig;
@@ -95,12 +93,11 @@
 * with clients over HTTP. The connection handler is responsible for
 * starting/stopping the embedded web server.
 */
public class HTTPConnectionHandler extends
    ConnectionHandler<HTTPConnectionHandlerCfg> implements
    ConfigurationChangeListener<HTTPConnectionHandlerCfg>,
    ServerShutdownListener, AlertGenerator
public class HTTPConnectionHandler extends ConnectionHandler<HTTPConnectionHandlerCfg>
                                   implements ConfigurationChangeListener<HTTPConnectionHandlerCfg>,
                                              ServerShutdownListener,
                                              AlertGenerator
{
  /** The tracer object for the debug logger. */
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
@@ -110,8 +107,7 @@
  /** 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);
  private static final ObjectMapper JSON_MAPPER = new ObjectMapper().configure(JsonParser.Feature.ALLOW_COMMENTS, true);
  /** The initialization configuration. */
  private HTTPConnectionHandlerCfg initConfig;
@@ -119,9 +115,7 @@
  /** The current configuration. */
  private HTTPConnectionHandlerCfg currentConfig;
  /**
   * Indicates whether the Directory Server is in the process of shutting down.
   */
  /** Indicates whether the Directory Server is in the process of shutting down. */
  private volatile boolean shutdownRequested;
  /** Indicates whether this connection handler is enabled. */
@@ -164,15 +158,10 @@
  /** The friendly name of this connection handler. */
  private String friendlyName;
  /**
   * The SSL engine configurator is used for obtaining default SSL parameters.
   */
  /** The SSL engine configurator is used for obtaining default SSL parameters. */
  private SSLEngineConfigurator sslEngineConfigurator;
  /**
   * Default constructor. It is invoked by reflection to create this
   * {@link ConnectionHandler}.
   */
  /** Default constructor. It is invoked by reflection to create this {@link ConnectionHandler}. */
  public HTTPConnectionHandler()
  {
    super(DEFAULT_FRIENDLY_NAME);
@@ -187,9 +176,8 @@
   */
  public boolean acceptUnauthenticatedRequests()
  {
    // the global setting overrides the more specific setting here.
    return !DirectoryServer.rejectUnauthenticatedRequests()
        && !this.currentConfig.isAuthenticationRequired();
    // The global setting overrides the more specific setting here.
    return !DirectoryServer.rejectUnauthenticatedRequests() && !this.currentConfig.isAuthenticationRequired();
  }
  /**
@@ -203,10 +191,8 @@
    clientConnections.put(clientConnection, clientConnection);
  }
  /** {@inheritDoc} */
  @Override
  public ConfigChangeResult applyConfigurationChange(
      HTTPConnectionHandlerCfg config)
  public ConfigChangeResult applyConfigurationChange(HTTPConnectionHandlerCfg config)
  {
    final ConfigChangeResult ccr = new ConfigChangeResult();
@@ -230,16 +216,17 @@
    }
    if (config.isEnabled() && this.currentConfig.isEnabled() && isListening())
    { // server was running and will still be running
      // if the "enabled" was flipped, leave it to the stop / start server to
      // handle it
    {
      // Server was running and will still be running if the "enabled" was flipped,
      // leave it to the stop / start server to handle it.
      if (!this.currentConfig.isKeepStats() && config.isKeepStats())
      { // it must now keep stats while it was not previously
      {
        // It must now keep stats while it was not previously.
        setHttpStatsProbe(this.httpServer);
      }
      else if (this.currentConfig.isKeepStats() && !config.isKeepStats()
          && this.httpProbe != null)
      { // it must NOT keep stats anymore
      else if (this.currentConfig.isKeepStats() && !config.isKeepStats() && this.httpProbe != null)
      {
        // It must NOT keep stats anymore.
        getHttpConfig(this.httpServer).removeProbes(this.httpProbe);
        this.httpProbe = null;
      }
@@ -296,7 +283,6 @@
    }
  }
  /** {@inheritDoc} */
  @Override
  public void finalizeConnectionHandler(LocalizableMessage finalizeReason)
  {
@@ -315,7 +301,6 @@
    }
  }
  /** {@inheritDoc} */
  @Override
  public Map<String, String> getAlerts()
  {
@@ -327,28 +312,24 @@
    return alerts;
  }
  /** {@inheritDoc} */
  @Override
  public String getClassName()
  {
    return HTTPConnectionHandler.class.getName();
  }
  /** {@inheritDoc} */
  @Override
  public Collection<ClientConnection> getClientConnections()
  {
    return clientConnections.keySet();
  }
  /** {@inheritDoc} */
  @Override
  public DN getComponentEntryDN()
  {
    return currentConfig.dn();
  }
  /** {@inheritDoc} */
  @Override
  public String getConnectionHandlerName()
  {
@@ -365,7 +346,6 @@
    return this.currentConfig;
  }
  /** {@inheritDoc} */
  @Override
  public Collection<String> getEnabledSSLCipherSuites()
  {
@@ -377,7 +357,6 @@
    return super.getEnabledSSLCipherSuites();
  }
  /** {@inheritDoc} */
  @Override
  public Collection<String> getEnabledSSLProtocols()
  {
@@ -389,7 +368,6 @@
    return super.getEnabledSSLProtocols();
  }
  /** {@inheritDoc} */
  @Override
  public Collection<HostPort> getListeners()
  {
@@ -406,7 +384,6 @@
    return this.initConfig.getListenPort();
  }
  /** {@inheritDoc} */
  @Override
  public String getProtocol()
  {
@@ -424,7 +401,6 @@
    return sslEngineConfigurator.createSSLEngine();
  }
  /** {@inheritDoc} */
  @Override
  public String getShutdownListenerName()
  {
@@ -441,7 +417,6 @@
    return statTracker;
  }
  /** {@inheritDoc} */
  @Override
  public void initializeConnectionHandler(HTTPConnectionHandlerCfg config)
      throws ConfigException, InitializationException
@@ -501,10 +476,9 @@
    return nameBuffer.toString();
  }
  /** {@inheritDoc} */
  @Override
  public boolean isConfigurationAcceptable(ConnectionHandlerCfg configuration,
      List<LocalizableMessage> unacceptableReasons)
  public boolean isConfigurationAcceptable(
      ConnectionHandlerCfg configuration, List<LocalizableMessage> unacceptableReasons)
  {
    HTTPConnectionHandlerCfg config = (HTTPConnectionHandlerCfg) configuration;
@@ -512,9 +486,8 @@
    {
      // Attempt to bind to the listen port on all configured addresses to
      // verify whether the connection handler will be able to start.
      LocalizableMessage errorMessage =
          checkAnyListenAddressInUse(config.getListenAddress(), config
              .getListenPort(), config.isAllowTCPReuseAddress(), config.dn());
      LocalizableMessage errorMessage = checkAnyListenAddressInUse(
          config.getListenAddress(), config.getListenPort(), config.isAllowTCPReuseAddress(), config.dn());
      if (errorMessage != null)
      {
        unacceptableReasons.add(errorMessage);
@@ -531,7 +504,6 @@
      catch (DirectoryException e)
      {
        logger.traceException(e);
        unacceptableReasons.add(e.getMessageObject());
        return false;
      }
@@ -556,8 +528,7 @@
   *         null otherwise.
   */
  private LocalizableMessage checkAnyListenAddressInUse(
      Collection<InetAddress> listenAddresses, int listenPort,
      boolean allowReuseAddress, DN configEntryDN)
      Collection<InetAddress> listenAddresses, int listenPort, boolean allowReuseAddress, DN configEntryDN)
  {
    for (InetAddress a : listenAddresses)
    {
@@ -571,14 +542,13 @@
      catch (IOException e)
      {
        logger.traceException(e);
        return ERR_CONNHANDLER_CANNOT_BIND.get("HTTP", configEntryDN, a.getHostAddress(), listenPort,
            getExceptionMessage(e));
        return ERR_CONNHANDLER_CANNOT_BIND.get(
            "HTTP", configEntryDN, a.getHostAddress(), listenPort, getExceptionMessage(e));
      }
    }
    return null;
  }
  /** {@inheritDoc} */
  @Override
  public boolean isConfigurationChangeAcceptable(
      HTTPConnectionHandlerCfg configuration, List<LocalizableMessage> unacceptableReasons)
@@ -597,7 +567,6 @@
    return currentConfig.isKeepStats();
  }
  /** {@inheritDoc} */
  @Override
  public void processServerShutdown(LocalizableMessage reason)
  {
@@ -609,14 +578,12 @@
    return httpServer != null;
  }
  /** {@inheritDoc} */
  @Override
  public void start()
  {
    // The Directory Server start process should only return
    // when the connection handlers port are fully opened
    // and working. The start method therefore needs to wait for
    // the created thread to
    // The Directory Server start process should only return when the connection handlers port
    // are fully opened and working.
    // The start method therefore needs to wait for the created thread too.
    synchronized (waitListen)
    {
      super.start();
@@ -627,8 +594,7 @@
      }
      catch (InterruptedException e)
      {
        // If something interrupted the start its probably better
        // to return ASAP.
        // If something interrupted the start its probably better to return ASAP
      }
    }
  }
@@ -644,7 +610,6 @@
    clientConnections.remove(clientConnection);
  }
  /** {@inheritDoc} */
  @Override
  public void run()
  {
@@ -655,8 +620,7 @@
    while (!shutdownRequested)
    {
      // If this connection handler is not enabled, then just sleep
      // for a bit and check again.
      // If this connection handler is not enabled, then just sleep for a bit and check again.
      if (!this.enabled)
      {
        if (isListening())
@@ -666,10 +630,8 @@
        if (starting)
        {
          // This may happen if there was an initialisation error
          // which led to disable the connector.
          // The main thread is waiting for the connector to listen
          // on its port, which will not occur yet,
          // This may happen if there was an initialisation error which led to disable the connector.
          // The main thread is waiting for the connector to listen on its port, which will not occur yet,
          // so notify here to allow the server startup to complete.
          synchronized (waitListen)
          {
@@ -691,45 +653,39 @@
      try
      {
        // At this point, the connection Handler either started
        // correctly or failed to start but the start process
        // should be notified and resume its work in any cases.
        // At this point, the connection Handler either started correctly or failed
        // to start but the start process should be notified and resume its work in any cases.
        synchronized (waitListen)
        {
          waitListen.notify();
        }
        // If we have gotten here, then we are about to start listening
        // for the first time since startup or since we were previously
        // disabled. Start the embedded HTTP server
        // for the first time since startup or since we were previously disabled.
        // Start the embedded HTTP server
        startHttpServer();
        lastIterationFailed = false;
      }
      catch (Exception e)
      {
        // clean up the messed up HTTP server
        // Clean up the messed up HTTP server
        cleanUpHttpServer();
        // error + alert about the horked config
        // Error + alert about the horked config
        logger.traceException(e);
        logger.error(ERR_CONNHANDLER_CANNOT_ACCEPT_CONNECTION,
            friendlyName, currentConfig.dn(), getExceptionMessage(e));
        logger.error(
            ERR_CONNHANDLER_CANNOT_ACCEPT_CONNECTION, friendlyName, currentConfig.dn(), getExceptionMessage(e));
        if (lastIterationFailed)
        {
          // The last time through the accept loop we also
          // encountered a failure. Rather than enter a potential
          // infinite loop of failures, disable this acceptor and
          // log an error.
          LocalizableMessage message =
              ERR_CONNHANDLER_CONSECUTIVE_ACCEPT_FAILURES.get(friendlyName,
                  currentConfig.dn(), stackTraceToSingleLineString(e));
          // The last time through the accept loop we also encountered a failure.
          // Rather than enter a potential infinite loop of failures,
          // disable this acceptor and log an error.
          LocalizableMessage message = ERR_CONNHANDLER_CONSECUTIVE_ACCEPT_FAILURES.get(
              friendlyName, currentConfig.dn(), stackTraceToSingleLineString(e));
          logger.error(message);
          DirectoryServer.sendAlertNotification(this,
              ALERT_TYPE_HTTP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, message);
          DirectoryServer.sendAlertNotification(this, ALERT_TYPE_HTTP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, message);
          this.enabled = false;
        }
        else
@@ -745,7 +701,7 @@
  private void startHttpServer() throws Exception
  {
    // silence Grizzly's own logging
    // Silence Grizzly's own logging
    Logger.getLogger("org.glassfish.grizzly").setLevel(Level.OFF);
    if (HTTPAccessLogger.getHTTPAccessLogPublishers().isEmpty())
@@ -755,7 +711,7 @@
    this.httpServer = createHttpServer();
    // register servlet as default servlet and also able to serve REST requests
    // Register servlet as default servlet and also able to serve REST requests
    createAndRegisterServlet("OpenDJ Rest2LDAP servlet", "", "/*");
    logger.trace("Starting HTTP server...");
@@ -779,31 +735,28 @@
      setHttpStatsProbe(server);
    }
    // configure the network listener
    final NetworkListener listener =
        new NetworkListener("Rest2LDAP", NetworkListener.DEFAULT_NETWORK_HOST,
            initConfig.getListenPort());
    // Configure the network listener
    final NetworkListener listener = new NetworkListener(
        "Rest2LDAP", NetworkListener.DEFAULT_NETWORK_HOST, initConfig.getListenPort());
    server.addListener(listener);
    // configure the network transport
    // Configure the network transport
    final TCPNIOTransport transport = listener.getTransport();
    transport.setReuseAddress(currentConfig.isAllowTCPReuseAddress());
    transport.setKeepAlive(currentConfig.isUseTCPKeepAlive());
    transport.setTcpNoDelay(currentConfig.isUseTCPNoDelay());
    transport.setWriteTimeout(currentConfig.getMaxBlockedWriteTimeLimit(),
        TimeUnit.MILLISECONDS);
    transport.setWriteTimeout(currentConfig.getMaxBlockedWriteTimeLimit(), TimeUnit.MILLISECONDS);
    final int bufferSize = (int) currentConfig.getBufferSize();
    transport.setReadBufferSize(bufferSize);
    transport.setWriteBufferSize(bufferSize);
    transport.setIOStrategy(SameThreadIOStrategy.getInstance());
    final int numRequestHandlers =
        getNumRequestHandlers(currentConfig.getNumRequestHandlers(),
            friendlyName);
    final int numRequestHandlers = getNumRequestHandlers(currentConfig.getNumRequestHandlers(), friendlyName);
    transport.setSelectorRunnersCount(numRequestHandlers);
    transport.setServerConnectionBackLog(currentConfig.getAcceptBacklog());
    // configure SSL
    // Configure SSL
    if (sslEngineConfigurator != null)
    {
      listener.setSecure(true);
@@ -821,54 +774,45 @@
  private MonitoringConfig<HttpProbe> getHttpConfig(HttpServer server)
  {
    final HttpServerMonitoringConfig monitoringCfg =
        server.getServerConfiguration().getMonitoringConfig();
    return monitoringCfg.getHttpConfig();
    return server.getServerConfiguration().getMonitoringConfig().getHttpConfig();
  }
  private void createAndRegisterServlet(final String servletName,
      final String... urlPatterns) throws Exception
  private void createAndRegisterServlet(final String servletName, final String... urlPatterns) throws Exception
  {
    // parse and use JSON config
    // Parse and use JSON config
    File jsonConfigFile = getFileForPath(this.currentConfig.getConfigFile());
    final JsonValue configuration =
        parseJsonConfiguration(jsonConfigFile).recordKeyAccesses();
    final HTTPAuthenticationConfig authenticationConfig =
        getAuthenticationConfig(configuration);
    final JsonValue configuration = parseJsonConfiguration(jsonConfigFile).recordKeyAccesses();
    final HTTPAuthenticationConfig authenticationConfig = getAuthenticationConfig(configuration);
    final ConnectionFactory connFactory = getConnectionFactory(configuration);
    configuration.verifyAllKeysAccessed();
    Filter filter =
        new CollectClientConnectionsFilter(this, authenticationConfig);
    final HttpServlet servlet = new HttpServlet(connFactory,
    Filter filter = new CollectClientConnectionsFilter(this, authenticationConfig);
    // Used for hooking our HTTPClientConnection in Rest2LDAP
        Rest2LDAPContextFactory.getHttpServletContextFactory());
    final HttpServlet servlet = new HttpServlet(connFactory, Rest2LDAPContextFactory.getHttpServletContextFactory());
    // Create and deploy the Web app context
    final WebappContext ctx = new WebappContext(servletName);
    ctx.addFilter("collectClientConnections", filter).addMappingForUrlPatterns(
        EnumSet.of(DispatcherType.REQUEST), true, urlPatterns);
    ctx.addFilter("collectClientConnections", filter)
       .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, urlPatterns);
    ctx.addServlet(servletName, servlet).addMapping(urlPatterns);
    ctx.deploy(this.httpServer);
  }
  private HTTPAuthenticationConfig getAuthenticationConfig(
      final JsonValue configuration)
  private HTTPAuthenticationConfig getAuthenticationConfig(final JsonValue configuration)
  {
    final HTTPAuthenticationConfig result = new HTTPAuthenticationConfig();
    final JsonValue val = configuration.get("authenticationFilter");
    result.setBasicAuthenticationSupported(asBool(val,
        "supportHTTPBasicAuthentication"));
    result.setCustomHeadersAuthenticationSupported(asBool(val,
        "supportAltAuthentication"));
    result.setCustomHeaderUsername(val.get("altAuthenticationUsernameHeader")
        .asString());
    result.setCustomHeaderPassword(val.get("altAuthenticationPasswordHeader")
        .asString());
    result.setBasicAuthenticationSupported(asBool(val, "supportHTTPBasicAuthentication"));
    result.setCustomHeadersAuthenticationSupported(asBool(val, "supportAltAuthentication"));
    result.setCustomHeaderUsername(val.get("altAuthenticationUsernameHeader").asString());
    result.setCustomHeaderPassword(val.get("altAuthenticationPasswordHeader").asString());
    final String searchBaseDN = asString(val, "searchBaseDN");
    result.setSearchBaseDN(org.forgerock.opendj.ldap.DN.valueOf(searchBaseDN));
    result.setSearchScope(SearchScope.valueOf(asString(val, "searchScope")));
    result.setSearchFilterTemplate(asString(val, "searchFilterTemplate"));
    return result;
  }
@@ -885,28 +829,27 @@
  private ConnectionFactory getConnectionFactory(final JsonValue configuration)
  {
    final Router router = new Router();
    final JsonValue mappings =
        configuration.get("servlet").get("mappings").required();
    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)
      final CollectionResourceProvider provider = Rest2LDAP.builder()
                                                           .authorizationPolicy(AuthorizationPolicy.REUSE)
              .configureMapping(mapping).build();
      router.addRoute(mappingUrl, provider);
    }
    return Resources.newInternalConnectionFactory(router);
  }
  private JsonValue parseJsonConfiguration(File configFile) throws IOException,
      JsonParseException, JsonMappingException, ServletException
  private JsonValue parseJsonConfiguration(File configFile)
      throws IOException, JsonParseException, JsonMappingException, ServletException
  {
    // 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");
      throw new ServletException(
          "Servlet configuration file '" + configFile + "' does not contain a valid JSON configuration");
    }
    return new JsonValue(content);
  }
@@ -929,15 +872,13 @@
    this.httpProbe = null;
  }
  /** {@inheritDoc} */
  @Override
  public void toString(StringBuilder buffer)
  {
    buffer.append(handlerName);
  }
  private SSLEngineConfigurator createSSLEngineConfigurator(
      HTTPConnectionHandlerCfg config) throws DirectoryException
  private SSLEngineConfigurator createSSLEngineConfigurator(HTTPConnectionHandlerCfg config) throws DirectoryException
  {
    if (!config.isUseSSL())
    {
@@ -947,8 +888,7 @@
    try
    {
      SSLContext sslContext = createSSLContext(config);
      SSLEngineConfigurator configurator =
          new SSLEngineConfigurator(sslContext);
      SSLEngineConfigurator configurator = new SSLEngineConfigurator(sslContext);
      configurator.setClientMode(false);
      // configure with defaults from the JVM
@@ -959,15 +899,13 @@
      final Set<String> protocols = config.getSSLProtocol();
      if (!protocols.isEmpty())
      {
        String[] array = protocols.toArray(new String[protocols.size()]);
        configurator.setEnabledProtocols(array);
        configurator.setEnabledProtocols(protocols.toArray(new String[protocols.size()]));
      }
      final Set<String> ciphers = config.getSSLCipherSuite();
      if (!ciphers.isEmpty())
      {
        String[] array = ciphers.toArray(new String[ciphers.size()]);
        configurator.setEnabledCipherSuites(array);
        configurator.setEnabledCipherSuites(ciphers.toArray(new String[ciphers.size()]));
      }
      switch (config.getSSLClientAuthPolicy())
@@ -993,14 +931,11 @@
    {
      logger.traceException(e);
      ResultCode resCode = DirectoryServer.getServerErrorResultCode();
      LocalizableMessage message =
          ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.get(getExceptionMessage(e));
      throw new DirectoryException(resCode, message, e);
      throw new DirectoryException(resCode, ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.get(getExceptionMessage(e)), e);
    }
  }
  private SSLContext createSSLContext(HTTPConnectionHandlerCfg config)
      throws Exception
  private SSLContext createSSLContext(HTTPConnectionHandlerCfg config) throws Exception
  {
    if (!config.isUseSSL())
    {
@@ -1008,8 +943,7 @@
    }
    DN keyMgrDN = config.getKeyManagerProviderDN();
    KeyManagerProvider<?> keyManagerProvider =
        DirectoryServer.getKeyManagerProvider(keyMgrDN);
    KeyManagerProvider<?> keyManagerProvider = DirectoryServer.getKeyManagerProvider(keyMgrDN);
    if (keyManagerProvider == null) {
      logger.error(ERR_NULL_KEY_PROVIDER_MANAGER, keyMgrDN, friendlyName);
      logger.warn(INFO_DISABLE_CONNECTION, friendlyName);
@@ -1036,14 +970,11 @@
        logger.warn(INFO_DISABLE_CONNECTION, friendlyName);
        enabled = false;
      }
      keyManagers =
          SelectableCertificateKeyManager.wrap(keyManagerProvider
              .getKeyManagers(), alias);
      keyManagers = SelectableCertificateKeyManager.wrap(keyManagerProvider.getKeyManagers(), alias);
    }
    DN trustMgrDN = config.getTrustManagerProviderDN();
    TrustManagerProvider<?> trustManagerProvider =
        DirectoryServer.getTrustManagerProvider(trustMgrDN);
    TrustManagerProvider<?> trustManagerProvider = DirectoryServer.getTrustManagerProvider(trustMgrDN);
    if (trustManagerProvider == null)
    {
      trustManagerProvider = new NullTrustManagerProvider();
@@ -1053,5 +984,4 @@
    sslContext.init(keyManagers, trustManagerProvider.getTrustManagers(), null);
    return sslContext;
  }
}
opendj-server-legacy/src/test/java/org/opends/server/protocols/http/CollectClientConnectionsFilterTest.java
@@ -21,7 +21,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2013 ForgeRock AS
 *      Copyright 2013-2015 ForgeRock AS
 */
package org.opends.server.protocols.http;
@@ -44,27 +44,22 @@
@SuppressWarnings("javadoc")
public class CollectClientConnectionsFilterTest extends DirectoryServerTestCase
{
  private static final String USERNAME = "Aladdin";
  private static final String PASSWORD = "open sesame";
  private static final String BASE64_USERPASS = Base64
      .encode((USERNAME + ":" + PASSWORD).getBytes());
  private static final String BASE64_USERPASS = Base64.encode((USERNAME + ":" + PASSWORD).getBytes());
  private HTTPAuthenticationConfig authConfig = new HTTPAuthenticationConfig();
  private CollectClientConnectionsFilter filter =
      new CollectClientConnectionsFilter(null, authConfig);
  private CollectClientConnectionsFilter filter = new CollectClientConnectionsFilter(null, authConfig);
  @DataProvider(name = "Invalid HTTP basic auth strings")
  public Object[][] getInvalidHttpBasicAuthStrings()
  {
    return new Object[][] { { null }, { "bla" },
      { "basic " + Base64.encode("la:bli:blu".getBytes()) } };
    return new Object[][] { { null }, { "bla" }, { "basic " + Base64.encode("la:bli:blu".getBytes()) } };
  }
  @Test(dataProvider = "Invalid HTTP basic auth strings")
  public void parseUsernamePasswordFromInvalidAuthZHeader(String authZHeader)
      throws Exception
  public void parseUsernamePasswordFromInvalidAuthZHeader(String authZHeader) throws Exception
  {
    assertThat(filter.parseUsernamePassword(authZHeader)).isNull();
  }
@@ -72,21 +67,17 @@
  @DataProvider(name = "Valid HTTP basic auth strings")
  public Object[][] getValidHttpBasicAuthStrings()
  {
    return new Object[][] { { "basic " + BASE64_USERPASS },
      { "Basic " + BASE64_USERPASS } };
    return new Object[][] { { "basic " + BASE64_USERPASS }, { "Basic " + BASE64_USERPASS } };
  }
  @Test(dataProvider = "Valid HTTP basic auth strings")
  public void parseUsernamePasswordFromValidAuthZHeader(String authZHeader)
      throws Exception
  public void parseUsernamePasswordFromValidAuthZHeader(String authZHeader) throws Exception
  {
    assertThat(filter.parseUsernamePassword(authZHeader)).containsExactly(
        USERNAME, PASSWORD);
    assertThat(filter.parseUsernamePassword(authZHeader)).containsExactly(USERNAME, PASSWORD);
  }
  @Test
  public void sendUnauthorizedResponseWithHttpBasicAuthWillChallengeUserAgent()
      throws Exception
  public void sendUnauthorizedResponseWithHttpBasicAuthWillChallengeUserAgent() throws Exception
  {
    authConfig.setBasicAuthenticationSupported(true);
@@ -96,14 +87,12 @@
    sendUnauthorizedResponseWithHTTPBasicAuthChallenge(response);
    verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    verify(response).setHeader("WWW-Authenticate",
        "Basic realm=\"org.forgerock.opendj\"");
    verify(response).setHeader("WWW-Authenticate", "Basic realm=\"org.forgerock.opendj\"");
    verifyUnauthorizedOutputMessage(response, oStream);
  }
  @Test
  public void sendUnauthorizedResponseWithoutHttpBasicAuthWillNotChallengeUserAgent()
      throws Exception
  public void sendUnauthorizedResponseWithoutHttpBasicAuthWillNotChallengeUserAgent() throws Exception
  {
    authConfig.setBasicAuthenticationSupported(true);
@@ -116,15 +105,14 @@
    verifyUnauthorizedOutputMessage(response, oStream);
  }
  private void sendUnauthorizedResponseWithHTTPBasicAuthChallenge(
      HttpServletResponse response)
  private void sendUnauthorizedResponseWithHTTPBasicAuthChallenge(HttpServletResponse response)
  {
    filter.sendErrorReponse(response, true, ResourceException.getException(
        HttpServletResponse.SC_UNAUTHORIZED, "Invalid Credentials"));
    filter.sendErrorReponse(
        response, true, ResourceException.getException(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Credentials"));
  }
  private void verifyUnauthorizedOutputMessage(HttpServletResponse response,
      ServletOutputStream oStream) throws IOException
  private void verifyUnauthorizedOutputMessage(HttpServletResponse response, ServletOutputStream oStream)
      throws IOException
  {
    verify(response).getOutputStream();
    verify(oStream).println(
@@ -134,17 +122,14 @@
  }
  @Test
  public void extractUsernamePasswordHttpBasicAuthWillAcceptUserAgent()
      throws Exception
  public void extractUsernamePasswordHttpBasicAuthWillAcceptUserAgent() throws Exception
  {
    authConfig.setBasicAuthenticationSupported(true);
    HttpServletRequest request = mock(HttpServletRequest.class);
    when(request.getHeader(HTTP_BASIC_AUTH_HEADER)).thenReturn(
        "Basic " + BASE64_USERPASS);
    when(request.getHeader(HTTP_BASIC_AUTH_HEADER)).thenReturn("Basic " + BASE64_USERPASS);
    assertThat(filter.extractUsernamePassword(request)).containsExactly(
        USERNAME, PASSWORD);
    assertThat(filter.extractUsernamePassword(request)).containsExactly(USERNAME, PASSWORD);
  }
  @Test
@@ -161,8 +146,6 @@
    when(request.getHeader(customHeaderUsername)).thenReturn(USERNAME);
    when(request.getHeader(customHeaderPassword)).thenReturn(PASSWORD);
    assertThat(filter.extractUsernamePassword(request)).containsExactly(
        USERNAME, PASSWORD);
    assertThat(filter.extractUsernamePassword(request)).containsExactly(USERNAME, PASSWORD);
  }
}