ProxyConnectionManager.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* --- BEGIN COPYRIGHT BLOCK ---
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2005 Red Hat, Inc.
  35. * All rights reserved.
  36. * --- END COPYRIGHT BLOCK --- */
  37. package com.netscape.dsml.gateway;
  38. import java.lang.Exception ;
  39. import java.util.*;
  40. import java.util.logging.*;
  41. import netscape.ldap.LDAPConnection;
  42. import netscape.ldap.util.ConnectionPool;
  43. import netscape.ldap.LDAPConstraints;
  44. import netscape.ldap.LDAPSearchConstraints;
  45. import netscape.ldap.controls.LDAPProxiedAuthControl;
  46. import netscape.ldap.LDAPBind;
  47. import netscape.ldap.LDAPException;
  48. import java.io.IOException;
  49. /**
  50. * ProxyConnectionManager is respossible for creating a pool of connections
  51. * to the directory server. The pool is initialized with configured set of
  52. * connections. Two pools are created; one for authentication and the other
  53. * for operations. The pool parameters (max and min) can be configured.
  54. *
  55. */
  56. class ProxyConnectionManager implements IConnectionManager {
  57. /*
  58. * Default maximum backlog queue size
  59. */
  60. static final int MAX_BACKLOG = 100;
  61. static final String LDAP_MAXBACKLOG = "maxbacklog";
  62. static final String LDAP_REFERRAL = "referral";
  63. private static Logger logger =
  64. Logger.getLogger("com.netscape.dsml.service.ProxyConnectionManager");
  65. static private ConnectionPool _ldapPool = null;
  66. static private ConnectionPool _ldapLoginPool = null;
  67. static private LDAPConnection _trialConn = null;
  68. static private LDAPSearchConstraints _defaultSearchConstraints = null;
  69. static private ProxyConnectionManager m_instance = null;
  70. private String m_host = null;
  71. private int m_port = 0;
  72. private String m_user = "";
  73. private String m_password = "";
  74. /**
  75. * Initialize by reading the informaton from the config manager.
  76. *
  77. * throws DSMLConfigException if unable to get the config
  78. * information.
  79. */
  80. private ProxyConnectionManager() {
  81. init();
  82. }
  83. private void init() {
  84. // Get an instance of the config manager
  85. Configuration config = Configuration.getInstance();
  86. m_host = config.getServerHost();
  87. m_port = config.getServerPort();
  88. m_user = config.getBindDN();
  89. m_password = config.getBindPW();
  90. logger.log(Level.INFO, "m_host: {0}", m_host);
  91. logger.log(Level.INFO, "m_port: {0}", String.valueOf(m_port) );
  92. logger.log(Level.INFO, "m_user: {0}", m_user);
  93. logger.log(Level.INFO, "m_password: {0}", m_password);
  94. logger.log(Level.FINER, "Initializing the ldap pool");
  95. initLdapPool( config.getMinPool(), config.getMaxPool());
  96. logger.log(Level.FINER, "Initializing the ldap LOGIN pool");
  97. initLoginPool(config.getMinLoginPool(), config.getMaxLoginPool());
  98. logger.log(Level.FINER, "Pool initialization done");
  99. }
  100. /**
  101. * create the singelton LDAPLayer object if it doesn't exist already.
  102. *
  103. * @exception DSMLConfigException if unable initialize configurations.
  104. */
  105. public static synchronized ProxyConnectionManager getInstance( ) {
  106. if (m_instance == null) {
  107. m_instance = new ProxyConnectionManager();
  108. }
  109. return m_instance;
  110. }
  111. /**
  112. * Get a connection to authenticate.
  113. *
  114. * @return a ldap connection handle
  115. *
  116. */
  117. public LDAPConnection getLoginConnection() {
  118. if (_ldapLoginPool == null ) {
  119. return null;
  120. }
  121. return _ldapLoginPool.getConnection();
  122. }
  123. /**
  124. * Returns the connection (used for authentication) to the pool.
  125. *
  126. */
  127. public void releaseLoginConnection(String _loginCtx, LDAPConnection conn ) {
  128. // Release the connection
  129. _ldapLoginPool.close( conn );
  130. }
  131. public void releaseLoginConnection(LDAPConnection conn ) {
  132. // Release the connection
  133. _ldapLoginPool.close( conn );
  134. }
  135. /**
  136. * Get connection from pool. This connection is used for
  137. * all operations except authentication.
  138. *
  139. * @param the loginctx (or the authenticated token)
  140. * @return connection that is available to use or null otherwise
  141. */
  142. public LDAPConnection getConnection(String loginCtx) {
  143. // XXX this behaves poorly if the server goes down.
  144. if (_ldapPool == null ) {
  145. return null;
  146. }
  147. LDAPConnection conn ;
  148. conn= _ldapPool.getConnection();
  149. return conn;
  150. }
  151. public LDAPConnection getConnection() {
  152. return getConnection("");
  153. }
  154. /**
  155. * Just call the pool method to release the connection so that the
  156. * given connection is free for others to use
  157. *
  158. * @param the login ctx used.
  159. * @param conn connection in the pool to be released for others to use
  160. */
  161. public void releaseConnection( String loginCtx, LDAPConnection conn ) {
  162. // Since we return the connecton to the pool and use a
  163. //proxy mode, loginCtx is not used.
  164. // XXX should change function signature
  165. if (_ldapPool == null || conn == null) return;
  166. // XXX reset the original constraints after before connection is released
  167. // conn.setSearchConstraints(_defaultSearchConstraints);
  168. // A soft close on the connection.
  169. // Returns the connection to the pool and make it available.
  170. _ldapPool.close( conn );
  171. }
  172. public void releaseConnection( LDAPConnection conn ) {
  173. if (_ldapPool == null || conn == null)
  174. return;
  175. // reset the original constraints
  176. //conn.setSearchConstraints(_defaultSearchConstraints);
  177. // A soft close on the connection.
  178. // Returns the connection to the pool and make it available.
  179. _ldapPool.close( conn );
  180. }
  181. /**
  182. * Initialize the pool shared by all. It is expected that the
  183. * host and port (and all configuration) information has been
  184. * initialized.
  185. */
  186. private synchronized void initLdapPool(int poolMin, int poolMax) {
  187. // Don't do anything if pool is already initialized
  188. if (_ldapPool != null) {
  189. logger.log(Level.FINER, "The pool is already initialized");
  190. return;
  191. }
  192. int maxBackLog = 10;
  193. boolean referrals = false;
  194. try {
  195. logger.log(Level.FINER, "Host={0}", m_host);
  196. logger.log(Level.FINER, "Port={0}", String.valueOf(m_port) );
  197. logger.log(Level.FINER, "DN={0}", m_user);
  198. logger.log(Level.FINE, "password={0}", m_password);
  199. _ldapPool = new ConnectionPool(poolMin, poolMax, m_host, m_port, m_user, m_password);
  200. logger.log(Level.FINER, "Pool initialized");
  201. } catch (LDAPException lde) {
  202. _ldapPool = null;
  203. logger.log(Level.SEVERE, "Pool not initialized\nError Code: " +
  204. lde.getLDAPResultCode() + "\n" + lde.getMessage() );
  205. } catch (Exception ex) {
  206. //logger.log(Level.SEVERE, "Pool init failed:{0}", ex.getMessage());
  207. //XXX throw new Exception("couldn't connect to ldap server");
  208. }
  209. }
  210. /*
  211. * Initialize the login pool. This pool of connections is used
  212. * for authentication.
  213. */
  214. private synchronized void initLoginPool(int poolMin, int poolMax) {
  215. if ( _ldapLoginPool != null)
  216. return;
  217. LDAPConnection conn = new LDAPConnection();
  218. logger.log(Level.FINER, "Creating the LOGIN Pool");
  219. try {
  220. conn.connect(3, m_host, m_port, m_user, m_password);
  221. _ldapLoginPool = new ConnectionPool(poolMin, poolMax, m_host, m_port, m_user, m_password);
  222. } catch (LDAPException lde) {
  223. _ldapLoginPool = null;
  224. logger.log(Level.SEVERE, "Pool not initialized\nError Code: " +
  225. lde.getLDAPResultCode() + "\n" +
  226. lde.getMessage() );
  227. } catch (Exception ex) {
  228. // logger.log(Level.SEVERE, "Pool init failed:{0}", ex.getMessage());
  229. //XXX throw new Exception("couldn't connect to ldap server");
  230. _ldapLoginPool = null;
  231. }
  232. }
  233. public void shutdown() {
  234. try {
  235. _ldapPool.destroy();
  236. } catch (java.lang.NullPointerException e ) {}
  237. try {
  238. _ldapLoginPool.destroy();
  239. } catch (java.lang.NullPointerException e) {}
  240. }
  241. }