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