8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * opensso/legal/CDDLv1.0.txt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at opensso/legal/CDDLv1.0.txt.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: SMDataLayer.java,v 1.16 2009/01/28 05:35:04 ww203982 Exp $
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Portions Copyrighted 2011-2015 ForgeRock AS.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpackage com.sun.identity.sm.ldap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static com.sun.identity.shared.Constants.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.am.util.SystemProperties;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.DSConfigMgr;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.LDAPServiceException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.LDAPUser;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.ServerGroup;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.ServerInstance;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.debug.Debug;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.concurrent.TimeUnit;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.openam.utils.StringUtils;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.opendj.ldap.Connection;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.opendj.ldap.ConnectionFactory;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.opendj.ldap.Connections;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.opendj.ldap.LdapException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.util.thread.listener.ShutdownListener;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.util.thread.listener.ShutdownManager;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * SMDataLayer (A PACKAGE SCOPE CLASS) to access LDAP or other database
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * TODO: 1. Needs to subclass and isolate the current implementation of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DataLayer as DSLayer for ldap specific operations 2. Improvements needed for
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * _ldapPool: destroy(), initial bind user, tunning for MIN and MAX initial
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * settings etc 3. May choose to extend implementation of _ldapPool from
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * LdapConnectionPool so that there is load balance between connections.Also
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * _ldapPool may be implemented with a HashTable of (host,port) for multiple
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * pools of connections for mulitple (host,port) to DS servers instead of single
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * host and port.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterclass SMDataLayer {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Static section to retrieve the debug object.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static Debug debug;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static SMDataLayer m_instance = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private ConnectionFactory _ldapPool = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * SMDataLayer constructor
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private SMDataLayer() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initLdapPool();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * create the singleton SMDataLayer object if it doesn't exist already.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster protected synchronized static SMDataLayer getInstance() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Obtain the Debug instance.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug = Debug.getInstance("amSMSLdap");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Make sure only one instance of this class is created.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (m_instance == null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster m_instance = new SMDataLayer();
}
return m_instance;
}
/**
* Get connection from pool, not through LDAPProxy. Reauthenticate if
* necessary
*
* @return connection that is available to use
*/
protected Connection getConnection() {
if (_ldapPool == null)
return null;
debug.message("SMDataLayer:getConnection() - Invoking _ldapPool.getConnection()");
Connection conn = null;
try {
conn = _ldapPool.getConnection();
debug.message("SMDataLayer:getConnection() - Got Connection : {}", conn);
} catch (LdapException e) {
debug.error("SMDataLayer:getConnection() - Failed to get Connection", e);
}
return conn;
}
/**
* Closes all the open ldap connections
*/
protected synchronized void shutdown() {
if (_ldapPool != null) {
_ldapPool.close();
}
_ldapPool = null;
m_instance = null;
}
/**
* Initialize the pool shared by all SMDataLayer object(s).
*/
private synchronized void initLdapPool() {
// Dont' do anything if pool is already initialized
if (_ldapPool != null)
return;
// Initialize the pool with minimum and maximum connections settings
// retrieved from configuration
ServerInstance svrCfg;
try {
DSConfigMgr dsCfg = DSConfigMgr.getDSConfigMgr();
// Get "sms" ServerGroup if present
ServerGroup sg = dsCfg.getServerGroup("sms");
final ConnectionFactory baseFactory;
if (sg != null) {
baseFactory = dsCfg.getNewConnectionFactory("sms",
LDAPUser.Type.AUTH_ADMIN);
svrCfg = sg.getServerInstance(LDAPUser.Type.AUTH_ADMIN);
} else {
baseFactory = dsCfg.getNewAdminConnectionFactory();
svrCfg = dsCfg.getServerInstance(LDAPUser.Type.AUTH_ADMIN);
}
if (svrCfg == null) {
debug.error("SMDataLayer:initLdapPool()-"
+ "Error getting server config.");
}
int poolMin = 1;
int poolMax = 2;
// Initialize the Connection Pool size only for the server
if (SystemProperties.isServerMode()) {
poolMin = svrCfg.getMinConnections();
poolMax = svrCfg.getMaxConnections();
}
debug.message("SMDataLayer:initLdapPool(): Creating ldap connection pool with: poolMin {} poolMax {}",
poolMin, poolMax);
int idleTimeout = SystemProperties.getAsInt(LDAP_CONN_IDLE_TIME_IN_SECS, 0);
if (idleTimeout == 0 && StringUtils.isNotBlank(SystemProperties.get(LDAP_CONN_IDLE_TIME_IN_SECS))) {
debug.error("SMDataLayer: Idle timeout could not be parsed, connection reaping is disabled");
} else if (idleTimeout == 0) {
debug.message("SMDataLayer: Idle timeout is set to 0 - connection reaping is disabled");
}
_ldapPool = Connections.newCachedConnectionPool(baseFactory, poolMin, poolMax,
idleTimeout, TimeUnit.SECONDS);
ShutdownManager shutdownMan = com.sun.identity.common.ShutdownManager.getInstance();
shutdownMan.addShutdownListener(
new ShutdownListener() {
public void shutdown() {
if (_ldapPool != null) {
_ldapPool.close();
}
}
}
);
} catch (LDAPServiceException ex) {
debug.error("SMDataLayer:initLdapPool()-"
+ "Error initializing connection pool " + ex.getMessage());
}
}
}