1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 * 19 */ 20 21 package org.apache.directory.ldap.client.api; 22 23 24 import org.apache.directory.api.asn1.util.Oid; 25 import org.apache.directory.api.ldap.model.exception.LdapException; 26 import org.apache.directory.api.ldap.model.message.BindRequest; 27 import org.apache.directory.api.ldap.model.message.ExtendedRequest; 28 import org.apache.directory.api.ldap.model.name.Dn; 29 import org.slf4j.Logger; 30 import org.slf4j.LoggerFactory; 31 32 33 /** 34 * A factory for creating LdapConnection objects managed by LdapConnectionPool. 35 * A bind operation is executed upon return if any of the following operations 36 * were performed on the connection while it was checked out: 37 * 38 * <ul> 39 * <li>{@link LdapConnection#bind() bind()}</li> 40 * <li>{@link LdapConnection#anonymousBind() anonymousBind()}</li> 41 * <li>{@link LdapConnection#bind(String) bind(String)}</li> 42 * <li>{@link LdapConnection#bind(String, String) bind(String, String)}</li> 43 * <li>{@link LdapConnection#bind(Dn) bind(Dn)}</li> 44 * <li>{@link LdapConnection#bind(Dn, String) bind(Dn, String)}</li> 45 * <li>{@link LdapConnection#bind(BindRequest) bind(BindRequest)}</li> 46 * <li>{@link LdapConnection#extended(String) extended(String)} <i>where oid is StartTLS</i></li> 47 * <li>{@link LdapConnection#extended(String, byte[]) extended(String, byte[])} <i>where oid is StartTLS</i></li> 48 * <li>{@link LdapConnection#extended(Oid) extended(String)} <i>where oid is StartTLS</i></li> 49 * <li>{@link LdapConnection#extended(Oid, byte[]) extended(String, byte[])} <i>where oid is StartTLS</i></li> 50 * <li>{@link LdapConnection#extended(ExtendedRequest) extended(ExtendedRequest)} <i>where ExtendedRequest is StartTLS</i></li> 51 * </ul> 52 * 53 * This is a <i>MOSTLY</i> safe way to handle connections in a pool. If one 54 * would like to use a slightly less expensive pool factory, the 55 * {@link DefaultPoolableLdapConnectionFactory} may be the right choice. 56 * 57 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 58 */ 59 public class ValidatingPoolableLdapConnectionFactory extends AbstractPoolableLdapConnectionFactory 60 { 61 /** This class logger */ 62 private static final Logger LOG = LoggerFactory.getLogger( ValidatingPoolableLdapConnectionFactory.class ); 63 64 65 /** 66 * Creates a new instance of ValidatingPoolableLdapConnectionFactory. 67 * 68 * @param config the configuration for creating LdapConnections 69 */ 70 public ValidatingPoolableLdapConnectionFactory( LdapConnectionConfig config ) 71 { 72 this( new DefaultLdapConnectionFactory( config ) ); 73 } 74 75 76 /** 77 * Creates a new instance of ValidatingPoolableLdapConnectionFactory. The 78 * <code>connectionFactoryClass</code> must have a public constructor accepting 79 * an <code>LdapConnectionConfig</code> object or an 80 * <code>IllegalArgumentException</code> will be thrown. 81 * 82 * @param config the configuration for creating LdapConnections 83 * @param connectionFactoryClass An implementation class of for the 84 * LDAP connection factory. 85 * @throws IllegalArgumentException If the instantiation of an instance of 86 * the <code>connectionFactoryClass</code> fails. 87 */ 88 public ValidatingPoolableLdapConnectionFactory( LdapConnectionConfig config, 89 Class<? extends LdapConnectionFactory> connectionFactoryClass ) 90 { 91 this( newLdapConnectionFactory( config, connectionFactoryClass ) ); 92 } 93 94 95 /** 96 * Creates a new instance of ValidatingPoolableLdapConnectionFactory. 97 * 98 * @param connectionFactory the connection factory for creating LdapConnections 99 */ 100 public ValidatingPoolableLdapConnectionFactory( LdapConnectionFactory connectionFactory ) 101 { 102 this.connectionFactory = connectionFactory; 103 } 104 105 106 /** 107 * {@inheritDoc} 108 * 109 * There is nothing to do to activate a connection. 110 */ 111 @Override 112 public void activateObject( LdapConnection connection ) throws LdapException 113 { 114 LOG.debug( "Activating {}", connection ); 115 super.activateObject( connection ); 116 117 // clear the monitors 118 ( ( MonitoringLdapConnection ) connection ).resetMonitors(); 119 } 120 121 122 /** 123 * {@inheritDoc} 124 * 125 * Specifically, we are creating a new connection based on the LdapConnection Factory 126 * we used to create this pool of connections. The default is to create bound connections. 127 * 128 * @throws LdapException If unable to connect. 129 */ 130 @Override 131 public MonitoringLdapConnection makeObject() throws LdapException 132 { 133 LOG.debug( "Creating a LDAP connection" ); 134 return new MonitoringLdapConnection( connectionFactory.newLdapConnection() ); 135 } 136 137 138 /** 139 * {@inheritDoc} 140 * 141 * Here, passivating a connection means we re-bind it, so that the existing LDAPSession 142 * is reset. 143 * 144 * @throws LdapException If unable to reconfigure and rebind. 145 */ 146 @Override 147 public void passivateObject( LdapConnection connection ) throws LdapException 148 { 149 LOG.debug( "Passivating {}", connection ); 150 151 if ( !connection.isConnected() || !connection.isAuthenticated() 152 || ( ( MonitoringLdapConnection ) connection ).bindCalled() ) 153 { 154 LOG.debug( "rebind due to bind on connection {}", connection ); 155 connectionFactory.bindConnection( connection ); 156 } 157 if ( ( ( MonitoringLdapConnection ) connection ).startTlsCalled() ) 158 { 159 LOG.debug( "unbind/rebind due to startTls on {}", connection ); 160 // unbind to clear the tls 161 connection.unBind(); 162 connectionFactory.bindConnection( connection ); 163 } 164 165 // in case connection had configuration changed 166 connectionFactory.configureConnection( connection ); 167 } 168 }