001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2012-2016 ForgeRock AS. 016 */ 017package org.opends.server.api; 018 019import static org.opends.messages.ProtocolMessages.*; 020 021import org.forgerock.i18n.slf4j.LocalizedLogger; 022 023import java.util.Collection; 024import java.util.Collections; 025import java.util.List; 026 027import org.forgerock.i18n.LocalizableMessage; 028import org.forgerock.opendj.server.config.server.ConnectionHandlerCfg; 029import org.opends.server.core.ServerContext; 030import org.forgerock.opendj.config.server.ConfigException; 031import org.opends.server.monitors.ConnectionHandlerMonitor; 032import org.forgerock.opendj.ldap.DN; 033import org.opends.server.types.HostPort; 034import org.opends.server.types.InitializationException; 035 036/** 037 * This class defines the set of methods and structures that must be 038 * implemented by a Directory Server connection handler. 039 * 040 * @param <T> 041 * The type of connection handler configuration handled by 042 * this connection handler implementation. 043 */ 044@org.opends.server.types.PublicAPI( 045 stability=org.opends.server.types.StabilityLevel.VOLATILE, 046 mayInstantiate=false, 047 mayExtend=true, 048 mayInvoke=false) 049public abstract class ConnectionHandler 050 <T extends ConnectionHandlerCfg> 051 extends DirectoryThread 052{ 053 054 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 055 056 /** The monitor associated with this connection handler. */ 057 private ConnectionHandlerMonitor monitor; 058 059 /** Is this handler the admin connection handler. */ 060 private boolean isAdminConnectionHandler; 061 062 063 064 /** 065 * Creates a new instance of this connection handler. This must be 066 * called by all connection handlers, and all connection handlers 067 * must provide default constructors (i.e., those that do not take 068 * any arguments) that invoke this constructor. 069 * 070 * @param threadName 071 * The name to use for this thread. 072 */ 073 protected ConnectionHandler(String threadName) { 074 super(threadName); 075 076 monitor = null; 077 } 078 079 080 081 /** 082 * Closes this connection handler so that it will no longer accept 083 * new client connections. Implementations should disconnect any 084 * existing connections. 085 * 086 * @param finalizeReason 087 * The reason that this connection handler should be 088 * finalized. 089 */ 090 public abstract void finalizeConnectionHandler( 091 LocalizableMessage finalizeReason); 092 093 094 095 /** 096 * Retrieves a name that may be used to refer to this connection 097 * handler. Every connection handler instance (even handlers of the 098 * same type) must have a unique name. 099 * 100 * @return A unique name that may be used to refer to this 101 * connection handler. 102 */ 103 public abstract String getConnectionHandlerName(); 104 105 106 107 /** 108 * Retrieves an unmodifiable set of enabled SSL cipher suites configured for 109 * this connection handler, if applicable. Implementations must return an 110 * empty set if use of SSL/TLS is not possible. 111 * 112 * @return The set of enabled SSL cipher suites configured for this connection 113 * handler. 114 */ 115 public Collection<String> getEnabledSSLCipherSuites() 116 { 117 return Collections.emptyList(); 118 } 119 120 121 122 /** 123 * Retrieves the set of enabled SSL protocols configured for this connection 124 * handler. Implementations must return an empty set if use of SSL/TLS is not 125 * possible. 126 * 127 * @return The set of enabled SSL protocols configured for this connection 128 * handler. 129 */ 130 public Collection<String> getEnabledSSLProtocols() 131 { 132 return Collections.emptyList(); 133 } 134 135 136 137 /** 138 * Retrieves the DN of the configuration entry with which this alert 139 * generator is associated. 140 * 141 * @return The DN of the configuration entry with which this alert 142 * generator is associated. 143 */ 144 public abstract DN getComponentEntryDN(); 145 146 /** 147 * Retrieves the name of the protocol used to communicate with 148 * clients. It should take into account any special naming that may 149 * be needed to express any security mechanisms or other constraints 150 * in place (e.g., "LDAPS" for LDAP over SSL). 151 * 152 * @return The name of the protocol used to communicate with 153 * clients. 154 */ 155 public abstract String getProtocol(); 156 157 158 159 /** 160 * Retrieves information about the listener(s) that will be used to 161 * accept client connections. 162 * 163 * @return Information about the listener(s) that will be used to 164 * accept client connections, or an empty list if this 165 * connection handler does not accept connections from 166 * network clients. 167 */ 168 public abstract Collection<HostPort> getListeners(); 169 170 171 172 /** 173 * Retrieves the set of active client connections that have been 174 * established through this connection handler. 175 * 176 * @return The set of active client connections that have been 177 * established through this connection handler. 178 */ 179 public abstract Collection<ClientConnection> getClientConnections(); 180 181 182 183 /** 184 * Initializes this connection handler provider based on the 185 * information in the provided connection handler configuration. 186 * 187 * @param serverContext 188 * The server context. 189 * @param configuration 190 * The connection handler configuration that contains the 191 * information to use to initialize this connection 192 * handler. 193 * @throws ConfigException 194 * If an unrecoverable problem arises in the process of 195 * performing the initialization as a result of the server 196 * configuration. 197 * @throws InitializationException 198 * If a problem occurs during initialization that is not 199 * related to the server configuration. 200 */ 201 public abstract void initializeConnectionHandler(ServerContext serverContext, T configuration) 202 throws ConfigException, InitializationException; 203 204 205 206 /** 207 * Indicates whether the provided configuration is acceptable for 208 * this connection handler. It should be possible to call this 209 * method on an uninitialized connection handler instance in order 210 * to determine whether the connection handler would be able to use 211 * the provided configuration. 212 * <BR><BR> 213 * Note that implementations which use a subclass of the provided 214 * configuration class will likely need to cast the configuration 215 * to the appropriate subclass type. 216 * 217 * @param configuration The connection handler configuration 218 * for which to make the determination. 219 * @param unacceptableReasons A list that may be used to hold the 220 * reasons that the provided 221 * configuration is not acceptable. 222 * 223 * @return {@code true} if the provided configuration is acceptable 224 * for this connection handler, or {@code false} if not. 225 */ 226 public boolean isConfigurationAcceptable( 227 ConnectionHandlerCfg configuration, 228 List<LocalizableMessage> unacceptableReasons) 229 { 230 // This default implementation does not perform any special 231 // validation. It should be overridden by connection handler 232 // implementations that wish to perform more detailed validation. 233 return true; 234 } 235 236 237 238 /** 239 * Operates in a loop, accepting new connections and ensuring that 240 * requests on those connections are handled properly. 241 */ 242 @Override 243 public abstract void run(); 244 245 246 247 /** 248 * Retrieves the monitor instance for this connection handler. 249 * 250 * @return The monitor instance for this connection handler, or 251 * {@code null} if none has been provided. 252 */ 253 public final ConnectionHandlerMonitor getConnectionHandlerMonitor() 254 { 255 return monitor; 256 } 257 258 259 260 /** 261 * Sets the monitor instance for this connection handler. 262 * 263 * @param monitor The monitor instance for this connection 264 * handler. 265 */ 266 public final void setConnectionHandlerMonitor( 267 ConnectionHandlerMonitor monitor) 268 { 269 this.monitor = monitor; 270 } 271 272 273 274 /** 275 * Sets this connection handler as the admin connection handler. 276 */ 277 public void setAdminConnectionHandler() { 278 isAdminConnectionHandler = true; 279 } 280 281 282 /** 283 * Returns whether this connection handler is the admin 284 * connection handler. 285 * @return boolean True if this connection handler is the admin 286 * connection handler, false otherwise 287 */ 288 public boolean isAdminConnectionHandler() { 289 return isAdminConnectionHandler; 290 } 291 292 293 /** 294 * Determine the number of request handlers. 295 * 296 * @param numRequestHandlers 297 * the number of request handlers from the configuration. 298 * @param friendlyName 299 * the friendly name of this connection handler 300 * @return the number of request handlers from the configuration determined 301 * from the configuration or from the number of available processors 302 * on the current machine 303 */ 304 public int getNumRequestHandlers(Integer numRequestHandlers, 305 String friendlyName) 306 { 307 if (numRequestHandlers == null) 308 { 309 // Automatically choose based on the number of processors. 310 int cpus = Runtime.getRuntime().availableProcessors(); 311 int value = Math.max(2, cpus / 2); 312 313 logger.debug(INFO_ERGONOMIC_SIZING_OF_REQUEST_HANDLER_THREADS, friendlyName, 314 value); 315 316 return value; 317 } 318 else 319 { 320 return numRequestHandlers; 321 } 322 } 323 324 /** 325 * Retrieves a string representation of this connection handler. 326 * 327 * @return A string representation of this connection handler. 328 */ 329 @Override 330 public String toString() { 331 StringBuilder buffer = new StringBuilder(); 332 toString(buffer); 333 return buffer.toString(); 334 } 335 336 337 338 /** 339 * Appends a string representation of this connection handler to the 340 * provided buffer. 341 * 342 * @param buffer 343 * The buffer to which the information should be appended. 344 */ 345 public abstract void toString(StringBuilder buffer); 346}