You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by lu...@apache.org on 2015/01/19 23:49:34 UTC
svn commit: r1653145 [2/2] - in /directory/shared/trunk: asn1/api/
asn1/api/src/main/java/org/apache/directory/api/asn1/util/
asn1/api/src/test/java/org/apache/directory/api/asn1/util/
asn1/api/src/test/resources/ asn1/ber/src/main/java/org/apache/dire...
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LookupLdapConnectionValidator.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LookupLdapConnectionValidator.java?rev=1653145&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LookupLdapConnectionValidator.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LookupLdapConnectionValidator.java Mon Jan 19 22:49:33 2015
@@ -0,0 +1,36 @@
+
+package org.apache.directory.ldap.client.api;
+
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.name.Dn;
+
+/**
+ * An implementation of {@link LdapConnectionValidator} that attempts a simple
+ * lookup on the rootDSE.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+final public class LookupLdapConnectionValidator implements LdapConnectionValidator
+{
+ /**
+ * Returns true if <code>connection</code> is connected, authenticated, and
+ * a lookup on the rootDSE returns a non-null response.
+ *
+ * @param connection The connection to validate
+ * @return True, if the connection is still valid
+ */
+ public boolean validate( LdapConnection connection )
+ {
+ try
+ {
+ return connection.isConnected()
+ && connection.isAuthenticated()
+ && ( connection.lookup( Dn.ROOT_DSE, SchemaConstants.NO_ATTRIBUTE ) != null );
+ }
+ catch ( LdapException e )
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LookupLdapConnectionValidator.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/MonitoringLdapConnection.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/MonitoringLdapConnection.java?rev=1653145&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/MonitoringLdapConnection.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/MonitoringLdapConnection.java Mon Jan 19 22:49:33 2015
@@ -0,0 +1,147 @@
+
+package org.apache.directory.ldap.client.api;
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.util.Oid;
+import org.apache.directory.api.ldap.extras.extended.startTls.StartTlsRequest;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.BindRequest;
+import org.apache.directory.api.ldap.model.message.BindResponse;
+import org.apache.directory.api.ldap.model.message.ExtendedRequest;
+import org.apache.directory.api.ldap.model.message.ExtendedResponse;
+import org.apache.directory.api.ldap.model.name.Dn;
+
+public final class MonitoringLdapConnection extends LdapConnectionWrapper
+{
+ private static final Oid START_TLS_OID;
+
+
+ static
+ {
+ try
+ {
+ START_TLS_OID = Oid.fromString( StartTlsRequest.EXTENSION_OID );
+ }
+ catch ( DecoderException e )
+ {
+ throw new IllegalStateException( "StartTlsRequest.EXTENSION_OID is not a valid oid... This cant happen" );
+ }
+ }
+
+
+ private boolean bindCalled = false;
+ private boolean startTlsCalled = false;
+
+ MonitoringLdapConnection( LdapConnection connection )
+ {
+ super( connection );
+ }
+
+ public boolean bindCalled() {
+ return bindCalled;
+ }
+
+ public void resetMonitors() {
+ bindCalled = false;
+ startTlsCalled = false;
+ }
+
+ public boolean startTlsCalled() {
+ return startTlsCalled;
+ }
+
+ @Override
+ public void bind() throws LdapException
+ {
+ connection.bind();
+ bindCalled = true;
+ }
+
+ @Override
+ public void anonymousBind() throws LdapException
+ {
+ connection.anonymousBind();
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( String name ) throws LdapException
+ {
+ connection.bind( name );
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( String name, String credentials ) throws LdapException
+ {
+ connection.bind( name, credentials );
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( Dn name ) throws LdapException
+ {
+ connection.bind( name );
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( Dn name, String credentials ) throws LdapException
+ {
+ connection.bind( name, credentials );
+ bindCalled = true;
+ }
+
+ @Override
+ public BindResponse bind( BindRequest bindRequest ) throws LdapException
+ {
+ BindResponse response = connection.bind( bindRequest );
+ bindCalled = true;
+ return response;
+ }
+
+ @Override
+ public ExtendedResponse extended( String oid ) throws LdapException
+ {
+ if ( StartTlsRequest.EXTENSION_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid );
+ }
+
+ @Override
+ public ExtendedResponse extended( String oid, byte[] value ) throws LdapException
+ {
+ if ( StartTlsRequest.EXTENSION_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid, value );
+ }
+
+ @Override
+ public ExtendedResponse extended( Oid oid ) throws LdapException
+ {
+ if ( START_TLS_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid );
+ }
+
+ @Override
+ public ExtendedResponse extended( Oid oid, byte[] value ) throws LdapException
+ {
+ if ( START_TLS_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid, value );
+ }
+
+ @Override
+ public ExtendedResponse extended( ExtendedRequest extendedRequest ) throws LdapException
+ {
+ if ( extendedRequest.hasControl( StartTlsRequest.EXTENSION_OID ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( extendedRequest );
+ }
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/MonitoringLdapConnection.java
------------------------------------------------------------------------------
svn:executable = *
Modified: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactory.java?rev=1653145&r1=1653144&r2=1653145&view=diff
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactory.java (original)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactory.java Mon Jan 19 22:49:33 2015
@@ -21,23 +21,38 @@
package org.apache.directory.ldap.client.api;
-import java.io.IOException;
-
-import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.asn1.util.Oid;
import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.BindRequest;
+import org.apache.directory.api.ldap.model.message.ExtendedRequest;
import org.apache.directory.api.ldap.model.name.Dn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * A factory for creating LdapConnection objects managed by LdapConnectionPool. The connections are validated
- * before being returned, which leads to a round-trip to the server. It also re-bind the connection when
- * it's being put back to the pool, to reset the LDAPSession.
+ * A factory for creating LdapConnection objects managed by LdapConnectionPool.
+ * A bind operation is executed upon return if any of the following operations
+ * were performed on the connection while it was checked out:
+ *
+ * <ul>
+ * <li>{@link LdapConnection#bind() bind()}</li>
+ * <li>{@link LdapConnection#anonymousBind() anonymousBind()}</li>
+ * <li>{@link LdapConnection#bind(String) bind(String)}</li>
+ * <li>{@link LdapConnection#bind(String, String) bind(String, String)}</li>
+ * <li>{@link LdapConnection#bind(Dn) bind(Dn)}</li>
+ * <li>{@link LdapConnection#bind(Dn, String) bind(Dn, String)}</li>
+ * <li>{@link LdapConnection#bind(BindRequest) bind(BindRequest)}</li>
+ * <li>{@link LdapConnection#extended(String) extended(String)} <i>where oid is StartTLS</i></li>
+ * <li>{@link LdapConnection#extended(String, byte[]) extended(String, byte[])} <i>where oid is StartTLS</i></li>
+ * <li>{@link LdapConnection#extended(Oid) extended(String)} <i>where oid is StartTLS</i></li>
+ * <li>{@link LdapConnection#extended(Oid, byte[]) extended(String, byte[])} <i>where oid is StartTLS</i></li>
+ * <li>{@link LdapConnection#extended(ExtendedRequest) extended(ExtendedRequest)} <i>where ExtendedRequest is StartTLS</i></li>
+ * </ul>
*
- * This is quite a costly - but secure - way to handle connections in a pool. If one would like to use a
- * less expensive pool factory, the {@link DefaultPoolableLdapConnectionFactory} is most certainly a better
- * choice.
+ * This is a <i>MOSTLY</i> safe way to handle connections in a pool. If one
+ * would like to use a slightly less expensive pool factory, the
+ * {@link DefaultPoolableLdapConnectionFactory} may be the right choice.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
@@ -48,7 +63,7 @@ public class ValidatingPoolableLdapConne
/**
- * Creates a new instance of PoolableLdapConnectionFactory.
+ * Creates a new instance of ValidatingPoolableLdapConnectionFactory.
*
* @param config the configuration for creating LdapConnections
*/
@@ -59,74 +74,63 @@ public class ValidatingPoolableLdapConne
/**
- * Creates a new instance of PoolableLdapConnectionFactory.
+ * Creates a new instance of ValidatingPoolableLdapConnectionFactory. The
+ * <code>connectionFactoryClass</code> must have a public constructor accepting
+ * an <code>LdapConnectionConfig</code> object or an
+ * <code>IllegalArgumentException</code> will be thrown.
*
- * @param connectionFactory the connection factory for creating LdapConnections
+ * @param config the configuration for creating LdapConnections
+ * @param connectionFactoryClass An implementation class of for the
+ * LDAP connection factory.
+ * @throws IllegalArgumentException If the instantiation of an instance of
+ * the <code>connectionFactoryClass</code> fails.
*/
- public ValidatingPoolableLdapConnectionFactory( LdapConnectionFactory connectionFactory )
+ public ValidatingPoolableLdapConnectionFactory( LdapConnectionConfig config,
+ Class<? extends LdapConnectionFactory> connectionFactoryClass )
{
- this.connectionFactory = connectionFactory;
+ this( newLdapConnectionFactory( config, connectionFactoryClass ) );
}
/**
- * {@inheritDoc}
- *
- * There is nothing to do to activate a connection.
+ * Creates a new instance of ValidatingPoolableLdapConnectionFactory.
+ *
+ * @param connectionFactory the connection factory for creating LdapConnections
*/
- public void activateObject( LdapConnection connection )
+ public ValidatingPoolableLdapConnectionFactory( LdapConnectionFactory connectionFactory )
{
- LOG.debug( "Activating {}", connection );
+ this.connectionFactory = connectionFactory;
}
/**
* {@inheritDoc}
*
- * Destroying a connection will unbind it which will result on a shutdown
- * of teh underlying protocol.
+ * There is nothing to do to activate a connection.
*/
- public void destroyObject( LdapConnection connection )
+ @Override
+ public void activateObject( LdapConnection connection ) throws LdapException
{
- LOG.debug( "Destroying {}", connection );
-
- if ( connection.isConnected() )
- {
- try
- {
- connection.unBind();
- }
- catch ( LdapException e )
- {
- LOG.error( "unable to unbind connection: {}", e.getMessage() );
- LOG.debug( "unable to unbind connection:", e );
- }
- }
+ LOG.debug( "Activating {}", connection );
+ super.activateObject( connection );
- try
- {
- connection.close();
- }
- catch ( IOException e )
- {
- LOG.error( "unable to close connection: {}", e.getMessage() );
- LOG.debug( "unable to close connection:", e );
- }
+ // clear the monitors
+ ( ( MonitoringLdapConnection ) connection ).resetMonitors();
}
/**
* {@inheritDoc}
+ *
* Specifically, we are creating a new connection based on the LdapConnection Factory
* we used to create this pool of connections. The default is to create bound connections.
*
* @throws LdapException If unable to connect.
*/
- public LdapConnection makeObject() throws LdapException
+ public MonitoringLdapConnection makeObject() throws LdapException
{
LOG.debug( "Creating a LDAP connection" );
-
- return connectionFactory.newLdapConnection();
+ return new MonitoringLdapConnection( connectionFactory.newLdapConnection() );
}
@@ -142,55 +146,21 @@ public class ValidatingPoolableLdapConne
{
LOG.debug( "Passivating {}", connection );
- // in case connection configuration was modified, or rebound to a
- // different identity, we reinitialize before returning to the pool.
- connectionFactory.bindConnection(
- connectionFactory.configureConnection( connection ) );
- }
-
-
- /**
- * {@inheritDoc}
- *
- * Validating a connection is done in depth : first we check that the connection is still
- * up, that the LdapSession is authenticated, and that we can retrieve some information
- * from the server. If the connection is not authenticated, we re-bind.
- */
- public boolean validateObject( LdapConnection connection )
- {
- LOG.debug( "Validating {}", connection );
-
- if ( connection.isConnected() )
+ if ( !connection.isConnected() || !connection.isAuthenticated()
+ || ( ( MonitoringLdapConnection ) connection ).bindCalled() )
{
- if ( connection.isAuthenticated() )
- {
- try
- {
- return connection.lookup( Dn.ROOT_DSE, SchemaConstants.NO_ATTRIBUTE ) != null;
- }
- catch ( LdapException le )
- {
- return false;
- }
- }
- else
- {
- // We have to bind the connection
- try
- {
- connectionFactory.bindConnection( connection );
-
- return true;
- }
- catch ( LdapException le )
- {
- return false;
- }
- }
+ LOG.debug( "rebind due to bind on connection {}", connection );
+ connectionFactory.bindConnection( connection );
}
- else
+ if ( ( ( MonitoringLdapConnection ) connection ).startTlsCalled() )
{
- return false;
+ LOG.debug( "unbind/rebind due to startTls on {}", connection );
+ // unbind to clear the tls
+ connection.unBind();
+ connectionFactory.bindConnection( connection );
}
+
+ // in case connection had configuration changed
+ connectionFactory.configureConnection( connection );
}
}
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/Wrapper.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/Wrapper.java?rev=1653145&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/Wrapper.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/Wrapper.java Mon Jan 19 22:49:33 2015
@@ -0,0 +1,17 @@
+package org.apache.directory.ldap.client.api;
+
+/**
+ * An interface for defining wrapper objects. An implementation of this class
+ * <b>MUST</b> implement <code>T</code> as well
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface Wrapper<T>
+{
+ /**
+ * Returns the wrapped object.
+ *
+ * @return The wrapped object
+ */
+ public T wrapped();
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/Wrapper.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/MockLdapConnectionFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/MockLdapConnectionFactory.java?rev=1653145&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/MockLdapConnectionFactory.java (added)
+++ directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/MockLdapConnectionFactory.java Mon Jan 19 22:49:33 2015
@@ -0,0 +1,35 @@
+package org.apache.directory.ldap.client.api;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.ldap.client.api.DefaultLdapConnectionFactory;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+
+public class MockLdapConnectionFactory extends DefaultLdapConnectionFactory
+{
+ Queue<LdapConnection> connections = new LinkedList<LdapConnection>();
+
+ public MockLdapConnectionFactory( LdapConnectionConfig config ) {
+ super( config );
+ }
+
+ public MockLdapConnectionFactory addConnection( LdapConnection connection ) {
+ this.connections.add( connection );
+ return this;
+ }
+
+ @Override
+ public LdapConnection newLdapConnection() throws LdapException
+ {
+ return bindConnection( this.connections.remove() );
+ }
+
+ @Override
+ public LdapConnection newUnboundLdapConnection()
+ {
+ return this.connections.remove();
+ }
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/MockLdapConnectionFactory.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactoryTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactoryTest.java?rev=1653145&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactoryTest.java (added)
+++ directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactoryTest.java Mon Jan 19 22:49:33 2015
@@ -0,0 +1,517 @@
+package org.apache.directory.ldap.client.api;
+
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.util.Oid;
+import org.apache.directory.api.ldap.extras.extended.startTls.StartTlsRequest;
+import org.apache.directory.api.ldap.extras.extended.startTls.StartTlsRequestImpl;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.BindRequest;
+import org.apache.directory.api.ldap.model.message.BindRequestImpl;
+import org.apache.directory.api.ldap.model.message.BindResponse;
+import org.apache.directory.api.ldap.model.message.ExtendedRequest;
+import org.apache.directory.api.ldap.model.message.ExtendedResponse;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.junit.Test;
+import org.mockito.exceptions.misusing.NotAMockException;
+import org.mockito.internal.util.MockUtil;
+import org.mockito.verification.VerificationMode;
+
+
+public class ValidatingPoolableLdapConnectionFactoryTest
+{
+ private static final String ADMIN_CREDENTIALS = "secret";
+ private static final String ADMIN_DN = "uid=admin, ou=system";
+ private static final MockUtil MOCK_UTIL = new MockUtil();
+
+
+ @Test
+ public void testPoolWithBind()
+ {
+ PoolTester tester = new PoolTester();
+
+ // no bind
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // bind()
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.bind();
+ verify( connection, times( 1 ) ).bind();
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // anonymousBind()
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.anonymousBind();
+ verify( connection, times( 1 ) ).anonymousBind();
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // bind( String )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.bind( "" );
+ verify( connection, times( 1 ) ).bind( "" );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // admin bind( String, String )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.bind( ADMIN_DN, ADMIN_CREDENTIALS );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // bind( String, String )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.bind( "", "" );
+ verify( connection, times( 1 ) ).bind( "", "" );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // bind( Dn )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ Dn dn = new Dn();
+ connection.bind( dn );
+ verify( connection, times( 1 ) ).bind( dn );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // bind( Dn, String )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ Dn dn = new Dn();
+ connection.bind( dn, "" );
+ verify( connection, times( 1 ) ).bind( dn, "" );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // bind( BindRequest );
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ BindRequest bindRequest = new BindRequestImpl();
+ connection.bind( bindRequest );
+ verify( connection, times( 1 ) ).bind( bindRequest );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+ }
+
+
+ @Test
+ public void testPoolWithStartTls()
+ {
+ PoolTester tester = new PoolTester();
+
+ // extended( String )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.extended( StartTlsRequest.EXTENSION_OID );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // extended( String, byte[] )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.extended( StartTlsRequest.EXTENSION_OID, new byte[] {} );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // extended( Oid )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ try
+ {
+ connection.extended( Oid.fromString( StartTlsRequest.EXTENSION_OID ) );
+ }
+ catch ( DecoderException e )
+ {
+ throw new IllegalArgumentException( "invalid oid: " + StartTlsRequest.EXTENSION_OID );
+ }
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // extended( Oid, byte[] )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ try
+ {
+ connection.extended( Oid.fromString( StartTlsRequest.EXTENSION_OID ), new byte[] {} );
+ }
+ catch ( DecoderException e )
+ {
+ throw new IllegalArgumentException( "invalid oid: " + StartTlsRequest.EXTENSION_OID );
+ }
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+
+ // extended( ExtendedRequest )
+ tester.execute(
+ new WithConnection()
+ {
+ @Override
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException
+ {
+ connection.extended( new StartTlsRequestImpl() );
+ verifyAdminBind( connection, times( counts.adminBindCount ) );
+ }
+ } );
+ }
+
+
+ private static final void verifyAdminBind( LdapConnection connection, VerificationMode mode ) throws LdapException
+ {
+ verify( connection, mode ).bind( ADMIN_DN, ADMIN_CREDENTIALS );
+ }
+
+
+ private static final LdapConnection verify( LdapConnection connection, VerificationMode mode )
+ {
+ if ( MOCK_UTIL.isMock( connection ) )
+ {
+ return org.mockito.Mockito.verify( connection, mode );
+ }
+ else
+ {
+ if ( connection instanceof Wrapper )
+ {
+ @SuppressWarnings("unchecked")
+ LdapConnection unwrapped = ( ( Wrapper<LdapConnection> ) connection ).wrapped();
+ return verify( unwrapped, mode );
+ }
+ }
+ throw new NotAMockException( "connection is not a mock, nor a wrapper for a connection that is one" );
+ }
+
+ private static final class Counts {
+ private int adminBindCount = 0;
+ private int unBindCount = 0;
+ }
+
+ public static final class InternalMonitoringLdapConnection extends LdapConnectionWrapper
+ {
+ private static final Oid START_TLS_OID;
+
+ static
+ {
+ try
+ {
+ START_TLS_OID = Oid.fromString( StartTlsRequest.EXTENSION_OID );
+ }
+ catch ( DecoderException e )
+ {
+ throw new IllegalStateException( "StartTlsRequest.EXTENSION_OID is not a valid oid... IMPOSSIBLE" );
+ }
+ }
+
+ private int borrowedCount = 0;
+ private boolean bindCalled = false;
+ private Counts counts = new Counts();
+ private boolean startTlsCalled = false;
+ private boolean unBindCalled = false;
+
+ InternalMonitoringLdapConnection( LdapConnection connection )
+ {
+ super( connection );
+ }
+
+ private int incrementBorrowedCount() {
+ return ++borrowedCount;
+ }
+
+ public boolean bindCalled() {
+ return bindCalled;
+ }
+
+ public void resetMonitors() {
+ bindCalled = false;
+ startTlsCalled = false;
+ unBindCalled = false;
+ }
+
+ public boolean startTlsCalled() {
+ return startTlsCalled;
+ }
+
+ public boolean unBindCalled() {
+ return unBindCalled;
+ }
+
+ @Override
+ public void bind() throws LdapException
+ {
+ connection.bind();
+ bindCalled = true;
+ }
+
+ @Override
+ public void anonymousBind() throws LdapException
+ {
+ connection.anonymousBind();
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( String name ) throws LdapException
+ {
+ connection.bind( name );
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( String name, String credentials ) throws LdapException
+ {
+ connection.bind( name, credentials );
+ if ( ADMIN_DN.equals( name )
+ && ADMIN_CREDENTIALS.equals( credentials ) ) {
+ counts.adminBindCount++;
+ }
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( Dn name ) throws LdapException
+ {
+ connection.bind( name );
+ bindCalled = true;
+ }
+
+ @Override
+ public void bind( Dn name, String credentials ) throws LdapException
+ {
+ connection.bind( name, credentials );
+ bindCalled = true;
+ }
+
+ @Override
+ public BindResponse bind( BindRequest bindRequest ) throws LdapException
+ {
+ BindResponse response = connection.bind( bindRequest );
+ bindCalled = true;
+ return response;
+ }
+
+ @Override
+ public ExtendedResponse extended( String oid ) throws LdapException
+ {
+ if ( StartTlsRequest.EXTENSION_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid );
+ }
+
+ @Override
+ public ExtendedResponse extended( String oid, byte[] value ) throws LdapException
+ {
+ if ( StartTlsRequest.EXTENSION_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid, value );
+ }
+
+ @Override
+ public ExtendedResponse extended( Oid oid ) throws LdapException
+ {
+ if ( START_TLS_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid );
+ }
+
+ @Override
+ public ExtendedResponse extended( Oid oid, byte[] value ) throws LdapException
+ {
+ if ( START_TLS_OID.equals( oid ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( oid, value );
+ }
+
+ @Override
+ public ExtendedResponse extended( ExtendedRequest extendedRequest ) throws LdapException
+ {
+ if ( extendedRequest.hasControl( StartTlsRequest.EXTENSION_OID ) ) {
+ startTlsCalled = true;
+ }
+ return connection.extended( extendedRequest );
+ }
+
+ @Override
+ public void unBind() throws LdapException {
+ counts.unBindCount++;
+ unBindCalled = true;
+ connection.unBind();
+ }
+ }
+
+
+ private static class PoolTester
+ {
+ private LdapConnectionConfig config;
+ private LdapConnectionPool pool;
+ private LdapConnectionValidator validator;
+
+
+ public PoolTester()
+ {
+ LdapConnection mockConnection = mock( LdapConnection.class );
+ when( mockConnection.isAuthenticated() ).thenReturn( true );
+ when( mockConnection.isConnected() ).thenReturn( true );
+
+ config = new LdapConnectionConfig();
+ config.setName( ADMIN_DN );
+ config.setCredentials( ADMIN_CREDENTIALS );
+
+ MockLdapConnectionFactory mockConnectionFactory = new MockLdapConnectionFactory( config );
+ mockConnectionFactory.addConnection(
+ new InternalMonitoringLdapConnection( mockConnection ) );
+
+ validator = mock( LdapConnectionValidator.class );
+ when( validator.validate( any( LdapConnection.class ) ) ).thenReturn( true );
+ ValidatingPoolableLdapConnectionFactory poolableFactory =
+ new ValidatingPoolableLdapConnectionFactory( mockConnectionFactory );
+ poolableFactory.setValidator( validator );
+
+ pool = new LdapConnectionPool( poolableFactory );
+ pool.setMaxActive( 1 );
+ pool.setTestOnBorrow( true );
+ pool.setTestOnReturn( true );
+ }
+
+
+ public void execute( WithConnection withConnection )
+ {
+ LdapConnection connection = null;
+ InternalMonitoringLdapConnection internal = null;
+ int borrowedCount = 0;
+ try
+ {
+ connection = pool.getConnection();
+ assertNotNull( connection );
+ internal = (InternalMonitoringLdapConnection)((LdapConnectionWrapper)connection).wrapped();
+ borrowedCount = internal.incrementBorrowedCount();
+ org.mockito.Mockito.verify( validator, times( 2 * borrowedCount - 1 ) ).validate( connection );
+ internal.resetMonitors();
+
+ withConnection.execute( connection, internal.counts );
+ }
+ catch ( LdapException e )
+ {
+ fail( "unable to getConnection(): " + e.getMessage() );
+ }
+ finally
+ {
+ try
+ {
+ int adminBindCount = internal.counts.adminBindCount;
+ pool.releaseConnection( connection );
+ org.mockito.Mockito.verify( validator, times( 2 * borrowedCount ) ).validate( connection );
+
+ if ( internal.startTlsCalled() )
+ {
+ verify( connection, times( internal.counts.unBindCount ) ).unBind();
+ }
+
+ int expectedCount = internal.bindCalled() || internal.startTlsCalled() || internal.unBindCalled()
+ ? adminBindCount + 1
+ : adminBindCount;
+ verifyAdminBind( connection, times( expectedCount ) );
+ }
+ catch ( LdapException e )
+ {
+ fail( "unable to releaseConnection(): " + e.getMessage() );
+ }
+ }
+ }
+ }
+
+
+ private static interface WithConnection
+ {
+ /**
+ * Executes code using the supplied connection.
+ *
+ * @param connection The ldap connection
+ * @param counts The counters for specific calls
+ */
+ public void execute( LdapConnection connection, Counts counts ) throws LdapException;
+ }
+}
Propchange: directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/ValidatingPoolableLdapConnectionFactoryTest.java
------------------------------------------------------------------------------
svn:executable = *
Modified: directory/shared/trunk/ldap/codec/core/src/main/java/org/apache/directory/api/ldap/codec/actions/extendedResponse/StoreExtendedResponseName.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/codec/core/src/main/java/org/apache/directory/api/ldap/codec/actions/extendedResponse/StoreExtendedResponseName.java?rev=1653145&r1=1653144&r2=1653145&view=diff
==============================================================================
--- directory/shared/trunk/ldap/codec/core/src/main/java/org/apache/directory/api/ldap/codec/actions/extendedResponse/StoreExtendedResponseName.java (original)
+++ directory/shared/trunk/ldap/codec/core/src/main/java/org/apache/directory/api/ldap/codec/actions/extendedResponse/StoreExtendedResponseName.java Mon Jan 19 22:49:33 2015
@@ -85,7 +85,7 @@ public class StoreExtendedResponseName e
}
else
{
- String responseName = new Oid( Strings.asciiBytesToString( tlv.getValue().getData() ) )
+ String responseName = Oid.fromString( Strings.asciiBytesToString( tlv.getValue().getData() ) )
.toString();
extendedResponse = LdapApiServiceFactory.getSingleton().newExtendedResponse( responseName,
Modified: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/startTls/StartTlsRequest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/startTls/StartTlsRequest.java?rev=1653145&r1=1653144&r2=1653145&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/startTls/StartTlsRequest.java (original)
+++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/startTls/StartTlsRequest.java Mon Jan 19 22:49:33 2015
@@ -24,12 +24,12 @@ import org.apache.directory.api.ldap.mod
/**
- * The RFC 4511 StartTLS request
+ * The <a href="http://tools.ietf.org/html/rfc4511">RFC 4511</a> StartTLS request
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public interface StartTlsRequest extends ExtendedRequest
{
- /** The OID for the StartTLS extended operation request. */
- String EXTENSION_OID = "1.3.6.1.4.1.1466.20037";
+ /** The OID string for the StartTLS extended operation request. */
+ static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20037";
}