001/* 002 * Copyright 2010-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2010-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.listener; 022 023 024 025import java.net.InetAddress; 026import javax.net.ServerSocketFactory; 027 028import com.unboundid.util.Mutable; 029import com.unboundid.util.ThreadSafety; 030import com.unboundid.util.ThreadSafetyLevel; 031import com.unboundid.util.Validator; 032 033 034 035/** 036 * This class provides a mechanism for defining the configuration to use for an 037 * {@link LDAPListener} instance. Note that while instances of this class are 038 * not inherently threadsafe, a private copy of the configuration will be 039 * created whenever a new {@code LDAPListener} is created so that this 040 * configuration may continue to be altered for new instances without impacting 041 * any existing listeners. 042 */ 043@Mutable() 044@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 045public final class LDAPListenerConfig 046{ 047 // Indicates whether to use the SO_KEEPALIVE socket option for sockets 048 // accepted by the listener. 049 private boolean useKeepAlive; 050 051 // Indicates whether to use the SO_LINGER socket option for sockets accepted 052 // by the listener. 053 private boolean useLinger; 054 055 // Indicates whether to use the SO_REUSEADDR socket option for sockets 056 // accepted by the listener. 057 private boolean useReuseAddress; 058 059 // Indicates whether to use the TCP_NODELAY for sockets accepted by the 060 // listener. 061 private boolean useTCPNoDelay; 062 063 // The address on which to listen for client connections. 064 private InetAddress listenAddress; 065 066 // The linger timeout in seconds to use for sockets accepted by the listener. 067 private int lingerTimeout; 068 069 // The port on which to listen for client connections. 070 private int listenPort; 071 072 // The receive buffer size to use for sockets accepted by the listener. 073 private int receiveBufferSize; 074 075 // The send buffer size to use for sockets accepted by the listener. 076 private int sendBufferSize; 077 078 // The exception handler to use for the listener and associated connections. 079 private LDAPListenerExceptionHandler exceptionHandler; 080 081 // The request handler that will be used to process requests read from 082 // clients. 083 private LDAPListenerRequestHandler requestHandler; 084 085 // The factory that will be used to create server sockets. 086 private ServerSocketFactory serverSocketFactory; 087 088 089 090 /** 091 * Creates a new listener configuration. 092 * 093 * @param listenPort The port on which to listen for client connections. 094 * It must be an integer between 1 and 65535, or 0 to 095 * indicate that a free port should be chosen by the 096 * JVM. 097 * @param requestHandler The request handler that will be used to process 098 * requests read from clients. It must not be 099 * {@code null}. 100 */ 101 public LDAPListenerConfig(final int listenPort, 102 final LDAPListenerRequestHandler requestHandler) 103 { 104 Validator.ensureTrue((listenPort >= 0) && (listenPort <= 65535)); 105 Validator.ensureNotNull(requestHandler); 106 107 this.listenPort = listenPort; 108 this.requestHandler = requestHandler; 109 110 useKeepAlive = true; 111 useLinger = true; 112 useReuseAddress = true; 113 useTCPNoDelay = true; 114 lingerTimeout = 5; 115 listenAddress = null; 116 receiveBufferSize = 0; 117 sendBufferSize = 0; 118 exceptionHandler = null; 119 serverSocketFactory = ServerSocketFactory.getDefault(); 120 } 121 122 123 124 /** 125 * Retrieves the port number on which to listen for client connections. A 126 * value of zero indicates that the listener should allow the JVM to choose a 127 * free port. 128 * 129 * @return The port number on which to listen for client connections. 130 */ 131 public int getListenPort() 132 { 133 return listenPort; 134 } 135 136 137 138 /** 139 * Specifies the port number on which to listen for client connections. The 140 * provided value must be between 1 and 65535, or it may be 0 to indicate that 141 * the JVM should select a free port on the system. 142 * 143 * @param listenPort The port number on which to listen for client 144 * connections. 145 */ 146 public void setListenPort(final int listenPort) 147 { 148 Validator.ensureTrue((listenPort >= 0) && (listenPort <= 65535)); 149 150 this.listenPort = listenPort; 151 } 152 153 154 155 /** 156 * Retrieves the LDAP listener request handler that should be used to process 157 * requests read from clients. 158 * 159 * @return The LDAP listener request handler that should be used to process 160 * requests read from clients. 161 */ 162 public LDAPListenerRequestHandler getRequestHandler() 163 { 164 return requestHandler; 165 } 166 167 168 169 /** 170 * Specifies the LDAP listener request handler that should be used to process 171 * requests read from clients. 172 * 173 * @param requestHandler The LDAP listener request handler that should be 174 * used to process requests read from clients. It 175 * must not be {@code null}. 176 */ 177 public void setRequestHandler(final LDAPListenerRequestHandler requestHandler) 178 { 179 Validator.ensureNotNull(requestHandler); 180 181 this.requestHandler = requestHandler; 182 } 183 184 185 186 /** 187 * Indicates whether to use the SO_KEEPALIVE socket option for sockets 188 * accepted by the listener. 189 * 190 * @return {@code true} if the SO_KEEPALIVE socket option should be used for 191 * sockets accepted by the listener, or {@code false} if not. 192 */ 193 public boolean useKeepAlive() 194 { 195 return useKeepAlive; 196 } 197 198 199 200 /** 201 * Specifies whether to use the SO_KEEPALIVE socket option for sockets 202 * accepted by the listener. 203 * 204 * @param useKeepAlive Indicates whether to use the SO_KEEPALIVE socket 205 * option for sockets accepted by the listener. 206 */ 207 public void setUseKeepAlive(final boolean useKeepAlive) 208 { 209 this.useKeepAlive = useKeepAlive; 210 } 211 212 213 214 /** 215 * Indicates whether to use the SO_LINGER socket option for sockets accepted 216 * by the listener. 217 * 218 * @return {@code true} if the SO_LINGER socket option should be used for 219 * sockets accepted by the listener, or {@code false} if not. 220 */ 221 public boolean useLinger() 222 { 223 return useLinger; 224 } 225 226 227 228 /** 229 * Specifies whether to use the SO_LINGER socket option for sockets accepted 230 * by the listener. 231 * 232 * @param useLinger Indicates whether to use the SO_LINGER socket option for 233 * sockets accepted by the listener. 234 */ 235 public void setUseLinger(final boolean useLinger) 236 { 237 this.useLinger = useLinger; 238 } 239 240 241 242 /** 243 * Indicates whether to use the SO_REUSEADDR socket option for sockets 244 * accepted by the listener. 245 * 246 * @return {@code true} if the SO_REUSEADDR socket option should be used for 247 * sockets accepted by the listener, or {@code false} if not. 248 */ 249 public boolean useReuseAddress() 250 { 251 return useReuseAddress; 252 } 253 254 255 256 /** 257 * Specifies whether to use the SO_REUSEADDR socket option for sockets 258 * accepted by the listener. 259 * 260 * @param useReuseAddress Indicates whether to use the SO_REUSEADDR socket 261 * option for sockets accepted by the listener. 262 */ 263 public void setUseReuseAddress(final boolean useReuseAddress) 264 { 265 this.useReuseAddress = useReuseAddress; 266 } 267 268 269 270 /** 271 * Indicates whether to use the TCP_NODELAY socket option for sockets accepted 272 * by the listener. 273 * 274 * @return {@code true} if the TCP_NODELAY socket option should be used for 275 * sockets accepted by the listener, or {@code false} if not. 276 */ 277 public boolean useTCPNoDelay() 278 { 279 return useTCPNoDelay; 280 } 281 282 283 284 /** 285 * Specifies whether to use the TCP_NODELAY socket option for sockets accepted 286 * by the listener. 287 * 288 * @param useTCPNoDelay Indicates whether to use the TCP_NODELAY socket 289 * option for sockets accepted by the listener. 290 */ 291 public void setUseTCPNoDelay(final boolean useTCPNoDelay) 292 { 293 this.useTCPNoDelay = useTCPNoDelay; 294 } 295 296 297 298 /** 299 * Retrieves the address on which to listen for client connections, if 300 * defined. 301 * 302 * @return The address on which to listen for client connections, or 303 * {@code null} if it should listen on all available addresses on all 304 * interfaces. 305 */ 306 public InetAddress getListenAddress() 307 { 308 return listenAddress; 309 } 310 311 312 313 /** 314 * Specifies the address on which to listen for client connections. 315 * 316 * @param listenAddress The address on which to listen for client 317 * connections. It may be {@code null} to indicate 318 * that it should listen on all available addresses on 319 * all interfaces. 320 */ 321 public void setListenAddress(final InetAddress listenAddress) 322 { 323 this.listenAddress = listenAddress; 324 } 325 326 327 328 /** 329 * Retrieves the timeout in seconds that should be used if the SO_LINGER 330 * socket option is enabled. 331 * 332 * @return The timeout in seconds that should be used if the SO_LINGER socket 333 * option is enabled. 334 */ 335 public int getLingerTimeoutSeconds() 336 { 337 return lingerTimeout; 338 } 339 340 341 342 /** 343 * Specifies the timeout in seconds that should be used if the SO_LINGER 344 * socket option is enabled. 345 * 346 * @param lingerTimeout The timeout in seconds that should be used if the 347 * SO_LINGER socket option is enabled. The value must 348 * be between 0 and 65535, inclusive. 349 */ 350 public void setLingerTimeoutSeconds(final int lingerTimeout) 351 { 352 Validator.ensureTrue((lingerTimeout >= 0) && (lingerTimeout <= 65535)); 353 354 this.lingerTimeout = lingerTimeout; 355 } 356 357 358 359 /** 360 * Retrieves the receive buffer size that should be used for sockets accepted 361 * by the listener. 362 * 363 * @return The receive buffer size that should be used for sockets accepted 364 * by the listener, or 0 if the default receive buffer size should be 365 * used. 366 */ 367 public int getReceiveBufferSize() 368 { 369 return receiveBufferSize; 370 } 371 372 373 374 /** 375 * Specifies the receive buffer size that should be used for sockets accepted 376 * by the listener. A value less than or equal to zero indicates that the 377 * default receive buffer size should be used. 378 * 379 * @param receiveBufferSize The receive buffer size that should be used for 380 * sockets accepted by the listener. 381 */ 382 public void setReceiveBufferSize(final int receiveBufferSize) 383 { 384 if (receiveBufferSize > 0) 385 { 386 this.receiveBufferSize = receiveBufferSize; 387 } 388 else 389 { 390 this.receiveBufferSize = 0; 391 } 392 } 393 394 395 396 /** 397 * Retrieves the send buffer size that should be used for sockets accepted 398 * by the listener. 399 * 400 * @return The send buffer size that should be used for sockets accepted by 401 * the listener, or 0 if the default send buffer size should be used. 402 */ 403 public int getSendBufferSize() 404 { 405 return sendBufferSize; 406 } 407 408 409 410 /** 411 * Specifies the send buffer size that should be used for sockets accepted by 412 * the listener. A value less than or equal to zero indicates that the 413 * default send buffer size should be used. 414 * 415 * @param sendBufferSize The send buffer size that should be used for 416 * sockets accepted by the listener. 417 */ 418 public void setSendBufferSize(final int sendBufferSize) 419 { 420 if (sendBufferSize > 0) 421 { 422 this.sendBufferSize = sendBufferSize; 423 } 424 else 425 { 426 this.sendBufferSize = 0; 427 } 428 } 429 430 431 432 /** 433 * Retrieves the exception handler that should be notified of any exceptions 434 * caught while attempting to accept or interact with a client connection. 435 * 436 * @return The exception handler that should be notified of any exceptions 437 * caught while attempting to accept or interact with a client 438 * connection, or {@code null} if none is defined. 439 */ 440 public LDAPListenerExceptionHandler getExceptionHandler() 441 { 442 return exceptionHandler; 443 } 444 445 446 447 /** 448 * Specifies the exception handler that should be notified of any exceptions 449 * caught while attempting to accept or interact with a client connection. 450 * 451 * @param exceptionHandler The exception handler that should be notified of 452 * any exceptions encountered during processing. It 453 * may be {@code null} if no exception handler 454 * should be used. 455 */ 456 public void setExceptionHandler( 457 final LDAPListenerExceptionHandler exceptionHandler) 458 { 459 this.exceptionHandler = exceptionHandler; 460 } 461 462 463 464 /** 465 * Retrieves the factory that will be used to create the server socket that 466 * will listen for client connections. 467 * 468 * @return The factory that will be used to create the server socket that 469 * will listen for client connections. 470 */ 471 public ServerSocketFactory getServerSocketFactory() 472 { 473 return serverSocketFactory; 474 } 475 476 477 478 /** 479 * Specifies the factory that will be used to create the server socket that 480 * will listen for client connections. 481 * 482 * @param serverSocketFactory The factory that will be used to create the 483 * server socket that will listen for client 484 * connections. It may be {@code null} to use 485 * the JVM-default server socket factory. 486 */ 487 public void setServerSocketFactory( 488 final ServerSocketFactory serverSocketFactory) 489 { 490 if (serverSocketFactory == null) 491 { 492 this.serverSocketFactory = ServerSocketFactory.getDefault(); 493 } 494 else 495 { 496 this.serverSocketFactory = serverSocketFactory; 497 } 498 } 499 500 501 502/** 503 * Creates a copy of this configuration that may be altered without impacting 504 * this configuration, and which will not be altered by changes to this 505 * configuration. 506 * 507 * @return A copy of this configuration that may be altered without impacting 508 * this configuration, and which will not be altered by changes to 509 * this configuration. 510 */ 511 public LDAPListenerConfig duplicate() 512 { 513 final LDAPListenerConfig copy = 514 new LDAPListenerConfig(listenPort, requestHandler); 515 516 copy.useKeepAlive = useKeepAlive; 517 copy.useLinger = useLinger; 518 copy.useReuseAddress = useReuseAddress; 519 copy.useTCPNoDelay = useTCPNoDelay; 520 copy.listenAddress = listenAddress; 521 copy.lingerTimeout = lingerTimeout; 522 copy.receiveBufferSize = receiveBufferSize; 523 copy.sendBufferSize = sendBufferSize; 524 copy.exceptionHandler = exceptionHandler; 525 copy.serverSocketFactory = serverSocketFactory; 526 527 return copy; 528 } 529}