From f2090c0d863b07e3bad8d16a3efddfad6ff77960 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Tue, 08 Oct 2013 14:16:54 +0000
Subject: [PATCH] Fix OPENDJ-346 Consider using java.util.ServiceLoader for loading extensions and requesting transport implementations This a a part of OPENDJ-175 - Decouple OpenDJ LDAP SDK from Grizzly CR-2440
---
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/TimeoutChecker.java | 10
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPServerFilter.java | 4
opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionTestCase.java | 13
opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java | 20
opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/TestCaseUtils.java | 47 ++
opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java | 22 +
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java | 41 +
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnection.java | 8
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionFactoryImpl.java | 52 ++
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/TransportProvider.java | 79 +++
opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java | 4
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java | 34 +
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/package-info.java | 31 +
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPListener.java | 45 +
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java | 46 ++
opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java | 41 +
opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java | 6
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/Provider.java | 45 ++
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListenerOptions.java | 114 +++-
opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/TestCaseUtils.java | 47 ++
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyTransportProvider.java | 81 +++
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPListenerImpl.java | 58 ++
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionFactory.java | 50 +
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPOptions.java | 133 ++++--
opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java | 22
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ProviderNotFoundException.java | 76 +++
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPClientFilter.java | 36
opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/AdaptersTestCase.java | 21
opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java | 94 +++-
opendj3/opendj-ldap-sdk/src/main/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider | 26 +
30 files changed, 1,092 insertions(+), 214 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnection.java
similarity index 99%
rename from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
rename to opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnection.java
index 77dbd01..d9c7968 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnection.java
@@ -87,7 +87,7 @@
/**
* LDAP connection implementation.
*/
-final class LDAPConnection extends AbstractAsynchronousConnection implements Connection {
+final class GrizzlyLDAPConnection extends AbstractAsynchronousConnection implements Connection {
/**
* A dummy SSL client engine configurator as SSLFilter only needs client
* config. This prevents Grizzly from needlessly using JVM defaults which
@@ -109,7 +109,7 @@
private final org.glassfish.grizzly.Connection<?> connection;
private final LDAPWriter ldapWriter = new LDAPWriter();
private final AtomicInteger nextMsgID = new AtomicInteger(1);
- private final LDAPConnectionFactoryImpl factory;
+ private final GrizzlyLDAPConnectionFactory factory;
private final ConcurrentHashMap<Integer, AbstractLDAPFutureResultImpl<?>> pendingRequests =
new ConcurrentHashMap<Integer, AbstractLDAPFutureResultImpl<?>>();
private final Object stateLock = new Object();
@@ -120,8 +120,8 @@
private boolean isFailed = false;
private List<ConnectionEventListener> listeners = null;
- LDAPConnection(final org.glassfish.grizzly.Connection<?> connection,
- final LDAPConnectionFactoryImpl factory) {
+ GrizzlyLDAPConnection(final org.glassfish.grizzly.Connection<?> connection,
+ final GrizzlyLDAPConnectionFactory factory) {
this.connection = connection;
this.factory = factory;
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionFactory.java
similarity index 84%
rename from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
rename to opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionFactory.java
index 91b4c93..00d09a7 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionFactory.java
@@ -29,6 +29,7 @@
import static com.forgerock.opendj.ldap.DefaultTCPNIOTransport.DEFAULT_TRANSPORT;
import static com.forgerock.opendj.ldap.TimeoutChecker.TIMEOUT_CHECKER;
+
import static org.forgerock.opendj.ldap.ErrorResultException.*;
import java.io.IOException;
@@ -40,7 +41,6 @@
import javax.net.ssl.SSLEngine;
import org.forgerock.opendj.ldap.Connection;
-import org.forgerock.opendj.ldap.ConnectionFactory;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.FutureResult;
import org.forgerock.opendj.ldap.LDAPOptions;
@@ -49,6 +49,7 @@
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.StartTLSExtendedRequest;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
+import org.forgerock.opendj.ldap.spi.LDAPConnectionFactoryImpl;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.EmptyCompletionHandler;
import org.glassfish.grizzly.SocketConnectorHandler;
@@ -62,9 +63,9 @@
import com.forgerock.opendj.util.ReferenceCountedObject;
/**
- * LDAP connection factory implementation.
+ * LDAP connection factory implementation using Grizzly for transport.
*/
-public final class LDAPConnectionFactoryImpl implements ConnectionFactory {
+public final class GrizzlyLDAPConnectionFactory implements LDAPConnectionFactoryImpl {
/**
* Adapts a Grizzly connection completion handler to an LDAP connection
* asynchronous future result.
@@ -88,7 +89,7 @@
@Override
public void completed(final org.glassfish.grizzly.Connection result) {
// Adapt the connection.
- final LDAPConnection connection = adaptConnection(result);
+ final GrizzlyLDAPConnection connection = adaptConnection(result);
// Plain connection.
if (options.getSSLContext() == null) {
@@ -159,14 +160,14 @@
// Ignore this.
}
- private LDAPConnection adaptConnection(final org.glassfish.grizzly.Connection<?> connection) {
+ private GrizzlyLDAPConnection adaptConnection(final org.glassfish.grizzly.Connection<?> connection) {
/*
* Test shows that its much faster with non block writes but risk
* running out of memory if the server is slow.
*/
connection.configureBlocking(true);
- final LDAPConnection ldapConnection =
- new LDAPConnection(connection, LDAPConnectionFactoryImpl.this);
+ final GrizzlyLDAPConnection ldapConnection =
+ new GrizzlyLDAPConnection(connection, GrizzlyLDAPConnectionFactory.this);
timeoutChecker.get().addConnection(ldapConnection);
clientFilter.registerConnection(connection, ldapConnection);
return ldapConnection;
@@ -184,14 +185,14 @@
}
}
- private void onFailure(final LDAPConnection connection, final Throwable t) {
+ private void onFailure(final GrizzlyLDAPConnection connection, final Throwable t) {
// Abort connection attempt due to error.
connection.close();
future.handleErrorResult(adaptConnectionException(t));
releaseTransportAndTimeoutChecker();
}
- private void onSuccess(final LDAPConnection connection) {
+ private void onSuccess(final GrizzlyLDAPConnection connection) {
future.handleResult(connection);
// Close the connection if the future was cancelled.
@@ -224,7 +225,7 @@
.acquire();
/**
- * Creates a new LDAP connection factory implementation which can be used to
+ * Creates a new LDAP connection factory based on Grizzly which can be used to
* create connections to the Directory Server at the provided host and port
* address using provided connection options.
*
@@ -233,14 +234,31 @@
* @param options
* The LDAP connection options to use when creating connections.
*/
- public LDAPConnectionFactoryImpl(final SocketAddress address, final LDAPOptions options) {
- this.transport = DEFAULT_TRANSPORT.acquireIfNull(options.getTCPNIOTransport());
+ public GrizzlyLDAPConnectionFactory(final SocketAddress address, final LDAPOptions options) {
+ this(address, options, null);
+ }
+
+ /**
+ * Creates a new LDAP connection factory based on Grizzly which can be used
+ * to create connections to the Directory Server at the provided host and
+ * port address using provided connection options and provided TCP
+ * transport.
+ *
+ * @param address
+ * The address of the Directory Server to connect to.
+ * @param options
+ * The LDAP connection options to use when creating connections.
+ * @param transport
+ * Grizzly TCP Transport NIO implementation to use for
+ * connections. If {@code null}, default transport will be used.
+ */
+ public GrizzlyLDAPConnectionFactory(final SocketAddress address, final LDAPOptions options,
+ TCPNIOTransport transport) {
+ this.transport = DEFAULT_TRANSPORT.acquireIfNull(transport);
this.socketAddress = address;
this.options = new LDAPOptions(options);
- this.clientFilter =
- new LDAPClientFilter(new LDAPReader(this.options.getDecodeOptions()), 0);
- this.defaultFilterChain =
- FilterChainBuilder.stateless().add(new TransportFilter()).add(clientFilter).build();
+ this.clientFilter = new LDAPClientFilter(new LDAPReader(this.options.getDecodeOptions()), 0);
+ this.defaultFilterChain = FilterChainBuilder.stateless().add(new TransportFilter()).add(clientFilter).build();
}
@Override
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPListenerImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPListener.java
similarity index 75%
rename from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPListenerImpl.java
rename to opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPListener.java
index cf540ec..d60d583 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPListenerImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyLDAPListener.java
@@ -30,14 +30,15 @@
import static com.forgerock.opendj.ldap.DefaultTCPNIOTransport.DEFAULT_TRANSPORT;
import static com.forgerock.opendj.util.StaticUtils.DEFAULT_LOG;
-import java.io.Closeable;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.concurrent.atomic.AtomicBoolean;
+
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.LDAPClientContext;
import org.forgerock.opendj.ldap.LDAPListenerOptions;
import org.forgerock.opendj.ldap.ServerConnectionFactory;
+import org.forgerock.opendj.ldap.spi.LDAPListenerImpl;
import org.glassfish.grizzly.filterchain.FilterChain;
import org.glassfish.grizzly.filterchain.FilterChainBuilder;
import org.glassfish.grizzly.filterchain.TransportFilter;
@@ -48,9 +49,9 @@
import com.forgerock.opendj.util.ReferenceCountedObject;
/**
- * LDAP listener implementation.
+ * LDAP listener implementation using Grizzly for transport.
*/
-public final class LDAPListenerImpl implements Closeable {
+public final class GrizzlyLDAPListener implements LDAPListenerImpl {
private final ReferenceCountedObject<TCPNIOTransport>.Reference transport;
private final FilterChain defaultFilterChain;
private final ServerConnectionFactory<LDAPClientContext, Integer> connectionFactory;
@@ -72,10 +73,35 @@
* If an error occurred while trying to listen on the provided
* address.
*/
- public LDAPListenerImpl(final SocketAddress address,
+ public GrizzlyLDAPListener(final SocketAddress address,
final ServerConnectionFactory<LDAPClientContext, Integer> factory,
final LDAPListenerOptions options) throws IOException {
- this.transport = DEFAULT_TRANSPORT.acquireIfNull(options.getTCPNIOTransport());
+ this(address, factory, options, null);
+ }
+
+ /**
+ * Creates a new LDAP listener implementation which will listen for LDAP
+ * client connections using the provided address, connection options and
+ * provided TCP transport.
+ *
+ * @param address
+ * The address to listen on.
+ * @param factory
+ * The server connection factory which will be used to create
+ * server connections.
+ * @param options
+ * The LDAP listener options.
+ * @param transport
+ * Grizzly TCP Transport NIO implementation to use for
+ * connections. If {@code null}, default transport will be used.
+ * @throws IOException
+ * If an error occurred while trying to listen on the provided
+ * address.
+ */
+ public GrizzlyLDAPListener(final SocketAddress address,
+ final ServerConnectionFactory<LDAPClientContext, Integer> factory,
+ final LDAPListenerOptions options, TCPNIOTransport transport) throws IOException {
+ this.transport = DEFAULT_TRANSPORT.acquireIfNull(transport);
this.connectionFactory = factory;
final DecodeOptions decodeOptions = new DecodeOptions(options.getDecodeOptions());
@@ -84,7 +110,7 @@
new LDAPServerFilter(this, new LDAPReader(decodeOptions), options
.getMaxRequestSize())).build();
final TCPNIOBindingHandler bindingHandler =
- TCPNIOBindingHandler.builder(transport.get()).processor(defaultFilterChain).build();
+ TCPNIOBindingHandler.builder(this.transport.get()).processor(defaultFilterChain).build();
this.serverConnection = bindingHandler.bind(address, options.getBacklog());
}
@@ -104,11 +130,8 @@
}
}
- /**
- * Returns the address that this LDAP listener is listening on.
- *
- * @return The address that this LDAP listener is listening on.
- */
+ /** {@inheritDoc} */
+ @Override
public SocketAddress getSocketAddress() {
return serverConnection.getLocalAddress();
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyTransportProvider.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyTransportProvider.java
new file mode 100644
index 0000000..680dc9d
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/GrizzlyTransportProvider.java
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+package com.forgerock.opendj.ldap;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+
+import org.forgerock.opendj.ldap.LDAPClientContext;
+import org.forgerock.opendj.ldap.LDAPListenerOptions;
+import org.forgerock.opendj.ldap.LDAPOptions;
+import org.forgerock.opendj.ldap.ServerConnectionFactory;
+import org.forgerock.opendj.ldap.spi.LDAPConnectionFactoryImpl;
+import org.forgerock.opendj.ldap.spi.LDAPListenerImpl;
+import org.forgerock.opendj.ldap.spi.TransportProvider;
+
+/**
+ * Provides an implementation of {@code LDAPListener} using Grizzly as
+ * transport.
+ * <p>
+ * To be used, this implementation must be declared in the
+ * provider-configuration file
+ * {@code META-INF/services/org.forgerock.opendj.ldap.spi.LDAPListenerProvider}
+ * with this single line:
+ *
+ * <pre>
+ * com.forgerock.opendj.ldap.GrizzlyLDAPListenerProvider
+ * </pre>.
+ * <p>
+ * To require that this implementation is used, you must set the transport
+ * provider to {@code Grizzly} using
+ * {@code LDAPListenerOptions#setTransportProvider(String)} method. Otherwise
+ * there is no guarantee that this implementation will be used.
+ */
+public class GrizzlyTransportProvider implements TransportProvider {
+
+ /** {@inheritDoc} */
+ @Override
+ public LDAPConnectionFactoryImpl getLDAPConnectionFactory(SocketAddress address, LDAPOptions options) {
+ return new GrizzlyLDAPConnectionFactory(address, options);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public LDAPListenerImpl getLDAPListener(
+ SocketAddress address,
+ ServerConnectionFactory<LDAPClientContext, Integer> factory,
+ LDAPListenerOptions options)
+ throws IOException {
+ return new GrizzlyLDAPListener(address, factory, options);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getName() {
+ return "Grizzly";
+ }
+
+}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPClientFilter.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPClientFilter.java
index f540a8d..eddd89c 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPClientFilter.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPClientFilter.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2010 Sun Microsystems, Inc.
- * Portions copyright 2012 ForgeRock AS.
+ * Portions copyright 2012-2013 ForgeRock AS.
*/
package com.forgerock.opendj.ldap;
@@ -67,7 +67,7 @@
* side logic for SSL and SASL operations over LDAP.
*/
final class LDAPClientFilter extends BaseFilter {
- private static final Attribute<LDAPConnection> LDAP_CONNECTION_ATTR =
+ private static final Attribute<GrizzlyLDAPConnection> LDAP_CONNECTION_ATTR =
Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute("LDAPClientConnection");
private static final Attribute<ASN1BufferReader> LDAP_ASN1_READER_ATTR =
Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute("LDAPASN1Reader");
@@ -80,7 +80,7 @@
@Override
public void addResult(final FilterChainContext ctx, final int messageID,
final Result result) throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -103,7 +103,7 @@
@Override
public void bindResult(final FilterChainContext ctx, final int messageID,
final BindResult result) throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -179,7 +179,7 @@
@Override
public void compareResult(final FilterChainContext ctx, final int messageID,
final CompareResult result) throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -200,7 +200,7 @@
@Override
public void deleteResult(final FilterChainContext ctx, final int messageID,
final Result result) throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -224,7 +224,7 @@
public void extendedResult(final FilterChainContext ctx, final int messageID,
final ExtendedResult result) throws UnexpectedResponseException,
IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
if (messageID == 0) {
@@ -274,7 +274,7 @@
public void intermediateResponse(final FilterChainContext ctx, final int messageID,
final IntermediateResponse response) throws UnexpectedResponseException,
IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -289,7 +289,7 @@
@Override
public void modifyDNResult(final FilterChainContext ctx, final int messageID,
final Result result) throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -312,7 +312,7 @@
@Override
public void modifyResult(final FilterChainContext ctx, final int messageID,
final Result result) throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -335,7 +335,7 @@
@Override
public void searchResult(final FilterChainContext ctx, final int messageID,
final Result result) throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -356,7 +356,7 @@
public void searchResultEntry(final FilterChainContext ctx, final int messageID,
final SearchResultEntry entry) throws UnexpectedResponseException,
IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -376,7 +376,7 @@
public void searchResultReference(final FilterChainContext ctx,
final int messageID, final SearchResultReference reference)
throws UnexpectedResponseException, IOException {
- final LDAPConnection ldapConnection =
+ final GrizzlyLDAPConnection ldapConnection =
LDAP_CONNECTION_ATTR.get(ctx.getConnection());
if (ldapConnection != null) {
final AbstractLDAPFutureResultImpl<?> pendingRequest =
@@ -395,7 +395,7 @@
// Needed in order to expose type information.
private <R extends ExtendedResult> void handleExtendedResult0(
- final LDAPConnection conn, final LDAPExtendedFutureResultImpl<R> future,
+ final GrizzlyLDAPConnection conn, final LDAPExtendedFutureResultImpl<R> future,
final ExtendedResult result) throws DecodeException {
final R decodedResponse =
future.decodeResult(result, conn.getLDAPOptions().getDecodeOptions());
@@ -457,7 +457,7 @@
// Just ignore errors on closed connections.
return;
}
- final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(connection);
+ final GrizzlyLDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(connection);
Result errorResult;
if (error instanceof EOFException) {
@@ -474,7 +474,7 @@
@Override
public NextAction handleClose(final FilterChainContext ctx) throws IOException {
final Connection<?> connection = ctx.getConnection();
- final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.remove(connection);
+ final GrizzlyLDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.remove(connection);
if (ldapConnection != null) {
final Result errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_SERVER_DOWN);
ldapConnection.close(null, false, errorResult);
@@ -499,7 +499,7 @@
ldapReader.decode(asn1Reader, CLIENT_RESPONSE_HANDLER, ctx);
}
} catch (IOException ioe) {
- final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx.getConnection());
+ final GrizzlyLDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx.getConnection());
final Result errorResult =
Responses.newResult(ResultCode.CLIENT_SIDE_DECODING_ERROR).setCause(ioe)
.setDiagnosticMessage(ioe.getMessage());
@@ -512,7 +512,7 @@
return ctx.getStopAction();
}
- void registerConnection(final Connection<?> connection, final LDAPConnection ldapConnection) {
+ void registerConnection(final Connection<?> connection, final GrizzlyLDAPConnection ldapConnection) {
LDAP_CONNECTION_ATTR.set(connection, ldapConnection);
}
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPServerFilter.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPServerFilter.java
index abd829a..4bbee8c 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPServerFilter.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPServerFilter.java
@@ -658,7 +658,7 @@
}
private final LDAPReader ldapReader;
- private final LDAPListenerImpl listener;
+ private final GrizzlyLDAPListener listener;
private final int maxASN1ElementSize;
private final AbstractLDAPMessageHandler<FilterChainContext> serverRequestHandler =
@@ -794,7 +794,7 @@
}
};
- LDAPServerFilter(final LDAPListenerImpl listener, final LDAPReader ldapReader,
+ LDAPServerFilter(final GrizzlyLDAPListener listener, final LDAPReader ldapReader,
final int maxASN1ElementSize) {
this.listener = listener;
this.ldapReader = ldapReader;
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/TimeoutChecker.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/TimeoutChecker.java
index 2ef5df9..2ecdd37 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/TimeoutChecker.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/TimeoutChecker.java
@@ -63,8 +63,8 @@
* The connection set must be safe from CMEs because expiring requests can
* cause the connection to be closed.
*/
- private final Set<LDAPConnection> connections =
- newSetFromMap(new ConcurrentHashMap<LDAPConnection, Boolean>());
+ private final Set<GrizzlyLDAPConnection> connections =
+ newSetFromMap(new ConcurrentHashMap<GrizzlyLDAPConnection, Boolean>());
/**
* Used to signal thread shutdown.
@@ -80,7 +80,7 @@
final long currentTime = System.currentTimeMillis();
long delay = 0;
- for (final LDAPConnection connection : connections) {
+ for (final GrizzlyLDAPConnection connection : connections) {
DEFAULT_LOG.trace("Checking connection {} delay = {}", connection, delay);
// May update the connections set.
@@ -113,12 +113,12 @@
checkerThread.start();
}
- void addConnection(final LDAPConnection connection) {
+ void addConnection(final GrizzlyLDAPConnection connection) {
connections.add(connection);
signal();
}
- void removeConnection(final LDAPConnection connection) {
+ void removeConnection(final GrizzlyLDAPConnection connection) {
connections.remove(connection);
// No need to signal.
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
index f14ad93..1c5f81e 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
@@ -45,6 +45,7 @@
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Locale;
+import java.util.ServiceLoader;
import java.util.TimeZone;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -60,6 +61,8 @@
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteStringBuilder;
+import org.forgerock.opendj.ldap.ProviderNotFoundException;
+import org.forgerock.opendj.ldap.spi.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -2256,4 +2259,47 @@
// No implementation required.
}
+ /**
+ * Find and returns a provider of one or more implementations.
+ * <p>
+ * The provider is loaded using the {@code ServiceLoader} facility.
+ *
+ * @param <P> type of provider
+ * @param providerClass
+ * class of provider
+ * @param requestedProvider
+ * name of provider to use, or {@code null} if no specific
+ * provider is requested.
+ * @param classLoader
+ * class loader to use to load the provider, or {@code null} to
+ * use the default class loader.
+ * @return a provider
+ * @throws ProviderNotFoundException
+ * if no provider is available or if the provider requested
+ * using options is not found.
+ */
+ public static <P extends Provider> P getProvider(final Class<P> providerClass, final String requestedProvider,
+ final ClassLoader classLoader) {
+
+ ServiceLoader<P> loader = ServiceLoader.load(providerClass, classLoader);
+ StringBuilder providersFound = new StringBuilder();
+ for (P provider : loader) {
+ if (providersFound.length() > 0) {
+ providersFound.append(" ");
+ }
+ providersFound.append(provider.getName());
+ if (requestedProvider == null || provider.getName().equals(requestedProvider)) {
+ return provider;
+ }
+ }
+ if (providersFound.length() > 0) {
+ throw new ProviderNotFoundException(providerClass, requestedProvider, String.format(
+ "The requested provider '%s' of type '%s' was not found. Available providers: %s",
+ requestedProvider, providerClass.getName(), providersFound));
+ } else {
+ throw new ProviderNotFoundException(providerClass, requestedProvider, String.format(
+ "There was no provider of type '%s' available.", providerClass.getName()));
+ }
+ }
+
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java
index 043e489..112b32e 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java
@@ -27,11 +27,15 @@
package org.forgerock.opendj.ldap;
+import static com.forgerock.opendj.util.StaticUtils.getProvider;
+
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
-import com.forgerock.opendj.ldap.LDAPConnectionFactoryImpl;
+import org.forgerock.opendj.ldap.spi.LDAPConnectionFactoryImpl;
+import org.forgerock.opendj.ldap.spi.TransportProvider;
+
import com.forgerock.opendj.util.Validator;
/**
@@ -45,6 +49,11 @@
*/
private final LDAPConnectionFactoryImpl impl;
+ /*
+ * Transport provider that provides the implementation of this factory.
+ */
+ private TransportProvider provider;
+
/**
* Creates a new LDAP connection factory which can be used to create LDAP
* connections to the Directory Server at the provided address.
@@ -53,6 +62,8 @@
* The address of the Directory Server.
* @throws NullPointerException
* If {@code address} was {@code null}.
+ * @throws ProviderNotFoundException if no provider is available or if the
+ * provider requested using options is not found.
*/
public LDAPConnectionFactory(final SocketAddress address) {
this(address, new LDAPOptions());
@@ -68,10 +79,14 @@
* The LDAP options to use when creating connections.
* @throws NullPointerException
* If {@code address} or {@code options} was {@code null}.
+ * @throws ProviderNotFoundException if no provider is available or if the
+ * provider requested using options is not found.
*/
public LDAPConnectionFactory(final SocketAddress address, final LDAPOptions options) {
Validator.ensureNotNull(address, options);
- this.impl = new LDAPConnectionFactoryImpl(address, options);
+ this.provider = getProvider(TransportProvider.class, options.getTransportProvider(),
+ options.getProviderClassLoader());
+ this.impl = provider.getLDAPConnectionFactory(address, options);
}
/**
@@ -85,6 +100,8 @@
* The port number.
* @throws NullPointerException
* If {@code host} was {@code null}.
+ * @throws ProviderNotFoundException if no provider is available or if the
+ * provider requested using options is not found.
*/
public LDAPConnectionFactory(final String host, final int port) {
this(host, port, new LDAPOptions());
@@ -103,11 +120,15 @@
* The LDAP options to use when creating connections.
* @throws NullPointerException
* If {@code host} or {@code options} was {@code null}.
+ * @throws ProviderNotFoundException if no provider is available or if the
+ * provider requested using options is not found.
*/
public LDAPConnectionFactory(final String host, final int port, final LDAPOptions options) {
Validator.ensureNotNull(host, options);
final SocketAddress address = new InetSocketAddress(host, port);
- this.impl = new LDAPConnectionFactoryImpl(address, options);
+ this.provider = getProvider(TransportProvider.class, options.getTransportProvider(),
+ options.getProviderClassLoader());
+ this.impl = provider.getLDAPConnectionFactory(address, options);
}
/**
@@ -175,14 +196,24 @@
}
/**
- * Returns the address that this LDAP listener is listening on.
+ * Returns the address used by the connections created by this factory.
*
- * @return The address that this LDAP listener is listening on.
+ * @return The address used by the connections.
*/
public SocketAddress getSocketAddress() {
return impl.getSocketAddress();
}
+ /**
+ * Returns the name of the transport provider, which provides the implementation
+ * of this factory.
+ *
+ * @return The name of actual transport provider.
+ */
+ public String getProviderName() {
+ return provider.getName();
+ }
+
@Override
public String toString() {
return impl.toString();
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java
index 4aa7445..bcbb5e4 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListener.java
@@ -27,13 +27,16 @@
package org.forgerock.opendj.ldap;
+import static com.forgerock.opendj.util.StaticUtils.*;
+
import java.io.Closeable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import org.forgerock.opendj.ldap.spi.LDAPListenerImpl;
+import org.forgerock.opendj.ldap.spi.TransportProvider;
-import com.forgerock.opendj.ldap.LDAPListenerImpl;
import com.forgerock.opendj.util.Validator;
/**
@@ -91,11 +94,16 @@
* </pre>
*/
public final class LDAPListener implements Closeable {
+
// We implement the factory using the pimpl idiom in order have
// cleaner Javadoc which does not expose implementation methods.
-
private final LDAPListenerImpl impl;
+ /*
+ * Transport provider that provides the implementation of this listener.
+ */
+ private TransportProvider provider;
+
/**
* Creates a new LDAP listener implementation which will listen for LDAP
* client connections at the provided address.
@@ -138,7 +146,9 @@
final LDAPListenerOptions options) throws IOException {
Validator.ensureNotNull(factory, options);
final SocketAddress address = new InetSocketAddress(port);
- this.impl = new LDAPListenerImpl(address, factory, options);
+ this.provider = getProvider(TransportProvider.class, options.getTransportProvider(),
+ options.getProviderClassLoader());
+ this.impl = provider.getLDAPListener(address, factory, options);
}
/**
@@ -183,7 +193,9 @@
final ServerConnectionFactory<LDAPClientContext, Integer> factory,
final LDAPListenerOptions options) throws IOException {
Validator.ensureNotNull(address, factory, options);
- this.impl = new LDAPListenerImpl(address, factory, options);
+ this.provider = getProvider(TransportProvider.class, options.getTransportProvider(),
+ options.getProviderClassLoader());
+ this.impl = provider.getLDAPListener(address, factory, options);
}
/**
@@ -233,7 +245,9 @@
final LDAPListenerOptions options) throws IOException {
Validator.ensureNotNull(host, factory, options);
final SocketAddress address = new InetSocketAddress(host, port);
- this.impl = new LDAPListenerImpl(address, factory, options);
+ this.provider = getProvider(TransportProvider.class, options.getTransportProvider(),
+ options.getProviderClassLoader());
+ this.impl = provider.getLDAPListener(address, factory, options);
}
/**
@@ -302,6 +316,16 @@
}
/**
+ * Returns the name of the transport provider, which provides the implementation
+ * of this factory.
+ *
+ * @return The name of actual transport provider.
+ */
+ public String getProviderName() {
+ return provider.getName();
+ }
+
+ /**
* {@inheritDoc}
*/
public String toString() {
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListenerOptions.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListenerOptions.java
index 3290349..696e4f4 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListenerOptions.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPListenerOptions.java
@@ -22,13 +22,11 @@
*
*
* Copyright 2010 Sun Microsystems, Inc.
- * Portions copyright 2012 ForgeRock AS.
+ * Portions copyright 2012-2013 ForgeRock AS.
*/
package org.forgerock.opendj.ldap;
-import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
-
import com.forgerock.opendj.util.Validator;
/**
@@ -39,17 +37,15 @@
private int backlog;
private DecodeOptions decodeOptions;
private int maxRequestSize;
- private TCPNIOTransport transport;
+ private ClassLoader providerClassLoader;
+ private String transportProvider;
/**
* Creates a new set of listener options with default settings. SSL will not
* be enabled, and a default set of decode options will be used.
*/
public LDAPListenerOptions() {
- this.backlog = 0;
- this.maxRequestSize = 0;
this.decodeOptions = new DecodeOptions();
- this.transport = null;
}
/**
@@ -63,7 +59,8 @@
this.backlog = options.backlog;
this.maxRequestSize = options.maxRequestSize;
this.decodeOptions = new DecodeOptions(options.decodeOptions);
- this.transport = options.transport;
+ this.providerClassLoader = options.providerClassLoader;
+ this.transportProvider = options.transportProvider;
}
/**
@@ -102,22 +99,6 @@
}
/**
- * Returns the Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server.
- * <p>
- * By default this method will return {@code null} indicating that the
- * default transport factory should be used to obtain a TCP transport.
- *
- * @return The Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server, or {@code null} if the
- * default transport factory should be used to obtain a TCP
- * transport.
- */
- public TCPNIOTransport getTCPNIOTransport() {
- return transport;
- }
-
- /**
* Sets the maximum queue length for incoming connections requests. If a
* connection request arrives when the queue is full, the connection is
* refused. If the backlog is less than {@code 1} then a default value of
@@ -165,21 +146,84 @@
}
/**
- * Sets the Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server.
+ * Gets the class loader which will be used to load the
+ * {@code TransportProvider}.
* <p>
* By default this method will return {@code null} indicating that the
- * default transport factory should be used to obtain a TCP transport.
+ * default class loader will be used.
+ * <p>
+ * The transport provider is loaded using {@code java.util.ServiceLoader},
+ * the JDK service-provider loading facility. The provider must be
+ * accessible from the same class loader that was initially queried to
+ * locate the configuration file; note that this is not necessarily the
+ * class loader from which the file was actually loaded. This method allows
+ * to provide a class loader to be used for loading the provider.
*
- * @param transport
- * The Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server, or {@code null} if the
- * default transport factory should be used to obtain a TCP
- * transport.
- * @return A reference to this connection options.
+ * @return The class loader which will be used to load the transport
+ * provider, or {@code null} if the default class loader should be
+ * used.
*/
- public LDAPListenerOptions setTCPNIOTransport(final TCPNIOTransport transport) {
- this.transport = transport;
+ public final ClassLoader getProviderClassLoader() {
+ return providerClassLoader;
+ }
+
+ /**
+ * Sets the class loader which will be used to load the
+ * {@code TransportProvider}.
+ * <p>
+ * The default class loader will be used if no class loader is set using
+ * this method.
+ * <p>
+ * The transport provider is loaded using {@code java.util.ServiceLoader},
+ * the JDK service-provider loading facility. The provider must be
+ * accessible from the same class loader that was initially queried to
+ * locate the configuration file; note that this is not necessarily the
+ * class loader from which the file was actually loaded. This method allows
+ * to provide a class loader to be used for loading the provider.
+ *
+ * @param classLoader
+ * The class loader which will be used load the transport
+ * provider, or {@code null} if the default class loader should
+ * be used.
+ * @return A reference to this LDAP listener options.
+ */
+ public final LDAPListenerOptions setProviderClassLoader(ClassLoader classLoader) {
+ this.providerClassLoader = classLoader;
+ return this;
+ }
+
+ /**
+ * Returns the name of the provider used for transport.
+ * <p>
+ * Transport providers implement {@code TransportProvider} interface.
+ * <p>
+ * The name should correspond to the name of an existing provider, as
+ * returned by {@code TransportProvider#getName()} method.
+ *
+ * @return The name of transport provider. The name is {@code null} if no
+ * specific provider has been selected. In that case, the first
+ * provider found will be used.
+ */
+ public String getTransportProvider() {
+ return transportProvider;
+ }
+
+ /**
+ * Sets the name of the provider to use for transport.
+ * <p>
+ * Transport providers implement {@code TransportProvider} interface.
+ * <p>
+ * The name should correspond to the name of an existing provider, as
+ * returned by {@code TransportProvider#getName()} method.
+ *
+ * @param providerName
+ * The name of transport provider, or {@code null} if no specific
+ * provider is preferred. In that case, the first provider found
+ * will be used.
+ * @return A reference to this LDAP listener options.
+ */
+ public LDAPListenerOptions setTransportProvider(String providerName) {
+ this.transportProvider = providerName;
return this;
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPOptions.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPOptions.java
index 4a8e8fc..9bcee09 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPOptions.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPOptions.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2010 Sun Microsystems, Inc.
- * Portions copyright 2012 ForgeRock AS.
+ * Portions copyright 2012-2013 ForgeRock AS.
*/
package org.forgerock.opendj.ldap;
@@ -33,8 +33,6 @@
import javax.net.ssl.SSLContext;
-import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
-
import com.forgerock.opendj.util.Validator;
/**
@@ -63,18 +61,15 @@
private DecodeOptions decodeOptions;
private List<String> enabledCipherSuites = new LinkedList<String>();
private List<String> enabledProtocols = new LinkedList<String>();
- private TCPNIOTransport transport;
+ private ClassLoader providerClassLoader;
+ private String transportProvider;
/**
* Creates a new set of connection options with default settings. SSL will
* not be enabled, and a default set of decode options will be used.
*/
public LDAPOptions() {
- this.sslContext = null;
- this.timeoutInMillis = 0;
- this.useStartTLS = false;
this.decodeOptions = new DecodeOptions();
- this.transport = null;
}
/**
@@ -91,7 +86,8 @@
this.decodeOptions = new DecodeOptions(options.decodeOptions);
this.enabledCipherSuites.addAll(options.getEnabledCipherSuites());
this.enabledProtocols.addAll(options.getEnabledProtocols());
- this.transport = options.transport;
+ this.providerClassLoader = options.providerClassLoader;
+ this.transportProvider = options.transportProvider;
}
/**
@@ -123,22 +119,6 @@
}
/**
- * Returns the Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server.
- * <p>
- * By default this method will return {@code null} indicating that the
- * default transport factory should be used to obtain a TCP transport.
- *
- * @return The Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server, or {@code null} if the
- * default transport factory should be used to obtain a TCP
- * transport.
- */
- public final TCPNIOTransport getTCPNIOTransport() {
- return transport;
- }
-
- /**
* Returns the operation timeout in the specified unit.
*
* @param unit
@@ -187,25 +167,6 @@
}
/**
- * Sets the Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server.
- * <p>
- * By default this method will return {@code null} indicating that the
- * default transport factory will be used to obtain a TCP transport.
- *
- * @param transport
- * The Grizzly TCP transport which will be used when initiating
- * connections with the Directory Server, or {@code null} if the
- * default transport factory should be used to obtain a TCP
- * transport.
- * @return A reference to this LDAP connection options.
- */
- public final LDAPOptions setTCPNIOTransport(final TCPNIOTransport transport) {
- this.transport = transport;
- return this;
- }
-
- /**
* Sets the operation timeout. If the response is not received from the
* Directory Server in the timeout period, the operation will be abandoned
* and an error result returned. A timeout setting of 0 disables timeout
@@ -315,4 +276,88 @@
return enabledCipherSuites;
}
+ /**
+ * Gets the class loader which will be used to load the
+ * {@code TransportProvider}.
+ * <p>
+ * By default this method will return {@code null} indicating that the
+ * default class loader will be used.
+ * <p>
+ * The transport provider is loaded using {@code java.util.ServiceLoader},
+ * the JDK service-provider loading facility. The provider must be
+ * accessible from the same class loader that was initially queried to
+ * locate the configuration file; note that this is not necessarily the
+ * class loader from which the file was actually loaded. This method allows
+ * to provide a class loader to be used for loading the provider.
+ *
+ * @return The class loader which will be used when loading the transport
+ * provider, or {@code null} if the default class loader should be
+ * used.
+ */
+ public final ClassLoader getProviderClassLoader() {
+ return providerClassLoader;
+ }
+
+ /**
+ * Sets the class loader which will be used to load the
+ * {@code TransportProvider}.
+ * <p>
+ * The default class loader will be used if no class loader is set using
+ * this method.
+ * <p>
+ * The transport provider is loaded using {@code java.util.ServiceLoader},
+ * the JDK service-provider loading facility. The provider must be
+ * accessible from the same class loader that was initially queried to
+ * locate the configuration file; note that this is not necessarily the
+ * class loader from which the file was actually loaded. This method allows
+ * to provide a class loader to be used for loading the provider.
+ *
+ * @param classLoader
+ * The class loader which will be used when loading the transport
+ * provider, or {@code null} if the default class loader should
+ * be used.
+ * @return A reference to this LDAP connection options.
+ */
+ public final LDAPOptions setProviderClassLoader(ClassLoader classLoader) {
+ this.providerClassLoader = classLoader;
+ return this;
+ }
+
+ /**
+ * Returns the name of the provider used for transport.
+ * <p>
+ * Transport providers implement {@code TransportProvider}
+ * interface.
+ * <p>
+ * The name should correspond to the name of an existing provider, as
+ * returned by {@code TransportProvider#getName()} method.
+ *
+ * @return The name of transport provider. The name is {@code null} if no
+ * specific provider has been selected. In that case, the first
+ * provider found will be used.
+ */
+ public String getTransportProvider() {
+ return transportProvider;
+ }
+
+ /**
+ * Sets the name of the provider to use for transport.
+ * <p>
+ * Transport providers implement {@code TransportProvider}
+ * interface.
+ * <p>
+ * The name should correspond to the name of an existing provider, as
+ * returned by {@code TransportProvider#getName()} method.
+ *
+ * @param providerName
+ * The name of transport provider, or {@code null} if no specific
+ * provider is preferred. In that case, the first provider found
+ * will be used.
+ * @return A reference to this LDAP connection options.
+ */
+ public LDAPOptions setTransportProvider(String providerName) {
+ this.transportProvider = providerName;
+ return this;
+ }
+
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ProviderNotFoundException.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ProviderNotFoundException.java
new file mode 100644
index 0000000..d11e447
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ProviderNotFoundException.java
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+
+package org.forgerock.opendj.ldap;
+
+import org.forgerock.opendj.ldap.spi.Provider;
+
+/**
+ * Exception thrown when a provider of a service can't be found.
+ */
+@SuppressWarnings("serial")
+public class ProviderNotFoundException extends RuntimeException {
+
+ private final Class<? extends Provider> providerType;
+ private final String providerName;
+
+ /**
+ * Creates the exception with a provider type, provider name and a message.
+ *
+ * @param providerClass
+ * the provider class
+ * @param providerName
+ * the name of the provider implementation that was requested
+ * @param message
+ * the detail message
+ */
+ public ProviderNotFoundException(final Class<? extends Provider> providerClass, final String providerName,
+ final String message) {
+ super(message);
+ this.providerType = providerClass;
+ this.providerName = providerName;
+ }
+
+ /**
+ * Returns the type of provider.
+ *
+ * @return the provider class
+ */
+ public Class<?> getProviderType() {
+ return providerType;
+ }
+
+ /**
+ * Returns the name of provider.
+ *
+ * @return the name of the provider implementation that was requested, or
+ * null if the default provider was requested.
+ */
+ public String getProviderName() {
+ return providerName;
+ }
+
+}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionFactoryImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionFactoryImpl.java
new file mode 100644
index 0000000..ed5d466
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPConnectionFactoryImpl.java
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.ldap.spi;
+
+import java.net.SocketAddress;
+
+import org.forgerock.opendj.ldap.ConnectionFactory;
+
+/**
+ * Interface for all classes that actually implement
+ * {@code LDAPConnectionFactory}.
+ * <p>
+ * An implementation class is provided by a {@code TransportProvider}.
+ * <p>
+ * The implementation can be automatically loaded using the
+ * {@code java.util.ServiceLoader} facility if its provider extending
+ * {@code TransportProvider} is declared in the provider-configuration file
+ * {@code META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider}.
+ */
+public interface LDAPConnectionFactoryImpl extends ConnectionFactory {
+
+ /**
+ * Returns the address used by the connections created by this factory.
+ *
+ * @return The address used by the connections.
+ */
+ public SocketAddress getSocketAddress();
+
+}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPListenerImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPListenerImpl.java
new file mode 100644
index 0000000..d8952f9
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/LDAPListenerImpl.java
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.ldap.spi;
+
+import java.io.Closeable;
+import java.net.SocketAddress;
+
+/**
+ * Interface for all classes that actually implement {@code LDAPListener}.
+ * <p>
+ * An implementation class is provided by a {@code TransportProvider}.
+ * <p>
+ * The implementation can be automatically loaded using the
+ * {@code java.util.ServiceLoader} facility if its provider extending
+ * {@code TransportProvider} is declared in the provider-configuration file
+ * {@code META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider}.
+ */
+public interface LDAPListenerImpl extends Closeable {
+
+ /**
+ * Returns the address that this LDAP listener is listening on.
+ *
+ * @return The address that this LDAP listener is listening on.
+ */
+ public SocketAddress getSocketAddress();
+
+ /**
+ * Closes this stream and releases any system resources associated
+ * with it. If the stream is already closed then invoking this
+ * method has no effect.
+ */
+ @Override
+ public void close();
+
+}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/Provider.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/Provider.java
new file mode 100644
index 0000000..2c0487e
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/Provider.java
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.ldap.spi;
+
+/**
+ * Interface for providers, which provide an implementation of one or more interfaces.
+ * <p>
+ * A provider must be declared in the provider-configuration file
+ * {@code META-INF/services/org.forgerock.opendj.ldap.spi.<ProviderClass>}
+ * in order to allow automatic loading of the implementation classes using the
+ * {@code java.util.ServiceLoader} facility.
+ */
+public interface Provider {
+
+ /**
+ * Returns the name of this provider.
+ *
+ * @return name of provider
+ */
+ String getName();
+
+}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/TransportProvider.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/TransportProvider.java
new file mode 100644
index 0000000..4b5bdc7
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/TransportProvider.java
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.ldap.spi;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+
+import org.forgerock.opendj.ldap.LDAPClientContext;
+import org.forgerock.opendj.ldap.LDAPListenerOptions;
+import org.forgerock.opendj.ldap.LDAPOptions;
+import org.forgerock.opendj.ldap.ServerConnectionFactory;
+
+/**
+ * Interface for transport providers, which provide implementation
+ * for {@code LDAPConnectionFactory} and {@code LDAPListener} classes,
+ * using a specific transport.
+ * <p>
+ * A transport provider must be declared in the provider-configuration file
+ * {@code META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider}
+ * in order to allow automatic loading of the implementation classes using the
+ * {@code java.util.ServiceLoader} facility.
+ */
+public interface TransportProvider extends Provider {
+
+ /**
+ * Returns an implementation of {@code LDAPConnectionFactory}.
+ *
+ * @param address
+ * The address of the Directory Server to connect to.
+ * @param options
+ * The LDAP options to use when creating connections.
+ * @return an implementation of {@code LDAPConnectionFactory}
+ */
+ LDAPConnectionFactoryImpl getLDAPConnectionFactory(SocketAddress address, LDAPOptions options);
+
+ /**
+ * Returns an implementation of {@code LDAPListener}.
+ *
+ * @param address
+ * The address to listen on.
+ * @param factory
+ * The server connection factory which will be used to create
+ * server connections.
+ * @param options
+ * The LDAP listener options.
+ * @return an implementation of {@code LDAPListener}
+ * @throws IOException
+ * If an error occurred while trying to listen on the provided
+ * address.
+ */
+ LDAPListenerImpl getLDAPListener(
+ SocketAddress address,
+ ServerConnectionFactory<LDAPClientContext, Integer> factory,
+ LDAPListenerOptions options) throws IOException;
+
+}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/package-info.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/package-info.java
new file mode 100644
index 0000000..b59caf0
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/spi/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+
+/**
+ * Interfaces and classes for service providers.
+ */
+package org.forgerock.opendj.ldap.spi;
+
diff --git a/opendj3/opendj-ldap-sdk/src/main/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider b/opendj3/opendj-ldap-sdk/src/main/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider
new file mode 100644
index 0000000..fa780e5
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/resources/META-INF/services/org.forgerock.opendj.ldap.spi.TransportProvider
@@ -0,0 +1,26 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+# or http://forgerock.org/license/CDDLv1.0.html.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at legal-notices/CDDLv1_0.txt.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information:
+# Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2013 ForgeRock AS.
+#
+com.forgerock.opendj.ldap.GrizzlyTransportProvider
\ No newline at end of file
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/LDAPConnectionTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionTestCase.java
similarity index 91%
rename from opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/LDAPConnectionTestCase.java
rename to opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionTestCase.java
index 5924e23..c1b271d 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/LDAPConnectionTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/GrizzlyLDAPConnectionTestCase.java
@@ -38,7 +38,6 @@
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.LDAPConnectionFactory;
import org.forgerock.opendj.ldap.LDAPListener;
-import org.forgerock.opendj.ldap.LDAPOptions;
import org.forgerock.opendj.ldap.RequestHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchResultHandler;
@@ -55,7 +54,7 @@
* Tests LDAP connection implementation class.
*/
@SuppressWarnings("javadoc")
-public class LDAPConnectionTestCase extends LDAPTestCase {
+public class GrizzlyLDAPConnectionTestCase extends LDAPTestCase {
/**
* Tests that a normal request is subject to client side timeout checking.
@@ -84,16 +83,16 @@
@SuppressWarnings("unchecked")
LDAPListener listener =
new LDAPListener(address, Connections
- .newServerConnectionFactory(mock(RequestHandler.class)));
+ .newServerConnectionFactory(mock(RequestHandler.class)),
+ TestCaseUtils.getLDAPListenerTestOptions());
/*
* Use a very long time out in order to prevent the timeout thread from
* triggering the timeout.
*/
- LDAPConnectionFactory factory =
- new LDAPConnectionFactory(address, new LDAPOptions().setTimeout(100,
- TimeUnit.SECONDS));
- LDAPConnection connection = (LDAPConnection) factory.getConnection();
+ LDAPConnectionFactory factory = new LDAPConnectionFactory(address,
+ TestCaseUtils.getLDAPTestOptions().setTimeout(100, TimeUnit.SECONDS));
+ GrizzlyLDAPConnection connection = (GrizzlyLDAPConnection) factory.getConnection();
try {
SearchRequest request =
Requests.newSearchRequest("dc=test", SearchScope.BASE_OBJECT, "(objectClass=*)");
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java
index 590268a..2319b8c 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java
@@ -28,13 +28,14 @@
package org.forgerock.opendj.ldap;
import static java.util.Arrays.asList;
+
+import static org.forgerock.opendj.ldap.TestCaseUtils.getLDAPTestOptions;
import static org.fest.assertions.Assertions.assertThat;
import static org.forgerock.opendj.ldap.Connections.newFixedConnectionPool;
import static org.forgerock.opendj.ldap.Connections.newHeartBeatConnectionFactory;
import static org.forgerock.opendj.ldap.Connections.newLoadBalancer;
import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
-import static org.forgerock.opendj.ldap.TestCaseUtils.findFreeSocketAddress;
-import static org.forgerock.opendj.ldap.TestCaseUtils.getServerSocketAddress;
+import static org.forgerock.opendj.ldap.TestCaseUtils.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doAnswer;
@@ -142,7 +143,8 @@
factories[0][0] =
Connections.newHeartBeatConnectionFactory(new LDAPConnectionFactory(
- getServerSocketAddress()), 1000, 500, TimeUnit.MILLISECONDS, request);
+ getServerSocketAddress(), getLDAPTestOptions()),
+ 1000, 500, TimeUnit.MILLISECONDS, request);
// InternalConnectionFactory
factories[1][0] = Connections.newInternalConnectionFactory(LDAPServer.getInstance(), null);
@@ -150,22 +152,25 @@
// AuthenticatedConnectionFactory
factories[2][0] =
new AuthenticatedConnectionFactory(new LDAPConnectionFactory(
- getServerSocketAddress()), Requests.newSimpleBindRequest("", new char[0]));
+ getServerSocketAddress(), getLDAPTestOptions()),
+ Requests.newSimpleBindRequest("", new char[0]));
// AuthenticatedConnectionFactory with multi-stage SASL
factories[3][0] =
new AuthenticatedConnectionFactory(new LDAPConnectionFactory(
- getServerSocketAddress()), Requests.newCRAMMD5SASLBindRequest("id:user",
+ getServerSocketAddress(), getLDAPTestOptions()),
+ Requests.newCRAMMD5SASLBindRequest("id:user",
"password".toCharArray()));
// LDAPConnectionFactory with default options
- factories[4][0] = new LDAPConnectionFactory(getServerSocketAddress());
+ factories[4][0] = new LDAPConnectionFactory(getServerSocketAddress(),
+ getLDAPTestOptions());
// LDAPConnectionFactory with startTLS
SSLContext sslContext =
new SSLContextBuilder().setTrustManager(TrustManagers.trustAll()).getSSLContext();
LDAPOptions options =
- new LDAPOptions().setSSLContext(sslContext).setUseStartTLS(true)
+ getLDAPTestOptions().setSSLContext(sslContext).setUseStartTLS(true)
.addEnabledCipherSuite(
new String[] { "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
@@ -188,12 +193,14 @@
// Connection pool and load balancing tests.
ConnectionFactory offlineServer1 =
- Connections.newNamedConnectionFactory(new LDAPConnectionFactory(findFreeSocketAddress()), "offline1");
+ Connections.newNamedConnectionFactory(new LDAPConnectionFactory(findFreeSocketAddress(),
+ getLDAPTestOptions()), "offline1");
ConnectionFactory offlineServer2 =
- Connections.newNamedConnectionFactory(new LDAPConnectionFactory(findFreeSocketAddress()), "offline2");
+ Connections.newNamedConnectionFactory(new LDAPConnectionFactory(findFreeSocketAddress(),
+ getLDAPTestOptions()), "offline2");
ConnectionFactory onlineServer =
Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
- getServerSocketAddress()), "online");
+ getServerSocketAddress(), getLDAPTestOptions()), "online");
// Connection pools.
factories[7][0] = Connections.newFixedConnectionPool(onlineServer, 10);
@@ -539,9 +546,11 @@
}
});
- LDAPListener listener = new LDAPListener(findFreeSocketAddress(), mockServer);
+ LDAPListener listener = new LDAPListener(findFreeSocketAddress(), mockServer,
+ TestCaseUtils.getLDAPListenerTestOptions());
try {
- LDAPConnectionFactory clientFactory = new LDAPConnectionFactory(listener.getSocketAddress());
+ LDAPConnectionFactory clientFactory =
+ new LDAPConnectionFactory(listener.getSocketAddress(), getLDAPTestOptions());
final Connection client = clientFactory.getConnection();
connectLatch.await(TEST_TIMEOUT, TimeUnit.SECONDS);
MockConnectionEventListener mockListener = null;
@@ -620,9 +629,11 @@
}
});
- LDAPListener listener = new LDAPListener(findFreeSocketAddress(), mockServer);
+ LDAPListener listener = new LDAPListener(findFreeSocketAddress(), mockServer,
+ getLDAPListenerTestOptions());
try {
- LDAPConnectionFactory clientFactory = new LDAPConnectionFactory(listener.getSocketAddress());
+ LDAPConnectionFactory clientFactory =
+ new LDAPConnectionFactory(listener.getSocketAddress(), getLDAPTestOptions());
final Connection client = clientFactory.getConnection();
connectLatch.await(TEST_TIMEOUT, TimeUnit.SECONDS);
try {
@@ -659,7 +670,7 @@
final ConnectionFactory factory =
newLoadBalancer(new FailoverLoadBalancingAlgorithm(asList(newFixedConnectionPool(
newHeartBeatConnectionFactory(new LDAPConnectionFactory(
- getServerSocketAddress())), 2))));
+ getServerSocketAddress(), getLDAPTestOptions())), 2))));
Connection conn = null;
try {
conn = factory.getConnection();
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java
index 01c2914..171df62 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java
@@ -27,6 +27,7 @@
import static org.fest.assertions.Assertions.assertThat;
import static org.forgerock.opendj.ldap.TestCaseUtils.findFreeSocketAddress;
+import static org.forgerock.opendj.ldap.TestCaseUtils.getLDAPTestOptions;
import static org.mockito.Mockito.mock;
import java.io.IOException;
@@ -44,6 +45,21 @@
// Test timeout for tests which need to wait for network events.
private static final long TEST_TIMEOUT = 30L;
+ @Test
+ public void testCreateLDAPConnectionFactory() throws Exception {
+ // test no exception is thrown, which means transport provider is correctly loaded
+ LDAPConnectionFactory factory = new LDAPConnectionFactory(findFreeSocketAddress(), getLDAPTestOptions());
+ factory.close();
+ }
+
+ @Test(expectedExceptions = { ProviderNotFoundException.class },
+ expectedExceptionsMessageRegExp = "^The requested provider 'unknown' .*")
+ public void testCreateLDAPConnectionFactoryFailureProviderNotFound() throws Exception {
+ LDAPOptions options = getLDAPTestOptions().setTransportProvider("unknown");
+ LDAPConnectionFactory factory = new LDAPConnectionFactory(findFreeSocketAddress(), options);
+ factory.close();
+ }
+
/**
* This unit test exposes the bug raised in issue OPENDJ-1156: NPE in
* ReferenceCountedObject after shutting down directory.
@@ -53,7 +69,8 @@
final AtomicReference<LDAPClientContext> context = new AtomicReference<LDAPClientContext>();
final Semaphore latch = new Semaphore(0);
final LDAPListener server = createServer(latch, context);
- final ConnectionFactory factory = new LDAPConnectionFactory(server.getSocketAddress());
+ final ConnectionFactory factory = new LDAPConnectionFactory(server.getSocketAddress(),
+ getLDAPTestOptions());
try {
for (int i = 0; i < 100; i++) {
// Connect to the server.
@@ -92,6 +109,7 @@
latch.release();
return mock(ServerConnection.class);
}
- });
+ },
+ TestCaseUtils.getLDAPListenerTestOptions());
}
}
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
index 711ef98..dda8d5d 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
@@ -29,6 +29,7 @@
import static org.fest.assertions.Assertions.*;
import static org.fest.assertions.Fail.*;
import static org.forgerock.opendj.ldap.TestCaseUtils.*;
+import static org.mockito.Mockito.*;
import java.net.InetSocketAddress;
import java.util.Arrays;
@@ -231,6 +232,31 @@
}
/**
+ * Test creation of LDAP listener with default transport provider.
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testCreateLDAPListener() throws Exception {
+ // test no exception is thrown, which means transport provider is
+ // correctly loaded
+ LDAPListener listener = new LDAPListener(findFreeSocketAddress(), mock(ServerConnectionFactory.class),
+ getLDAPListenerTestOptions());
+ listener.close();
+ }
+
+ /**
+ * Test creation of LDAP listener with unknown transport provider.
+ */
+ @SuppressWarnings({ "unused", "resource", "unchecked" })
+ @Test(expectedExceptions = { ProviderNotFoundException.class },
+ expectedExceptionsMessageRegExp = "^The requested provider 'unknown' .*")
+ public void testCreateLDAPListenerFailureProviderNotFound() throws Exception {
+ LDAPListenerOptions options = getLDAPListenerTestOptions().setTransportProvider("unknown");
+ LDAPListener listener = new LDAPListener(findFreeSocketAddress(), mock(ServerConnectionFactory.class), options);
+ listener.close();
+ }
+
+ /**
* Tests basic LDAP listener functionality.
*
* @throws Exception
@@ -242,11 +268,13 @@
final MockServerConnectionFactory serverConnectionFactory =
new MockServerConnectionFactory(serverConnection);
final LDAPListener listener =
- new LDAPListener(new InetSocketAddress(0), serverConnectionFactory);
+ new LDAPListener(new InetSocketAddress(0), serverConnectionFactory,
+ TestCaseUtils.getLDAPListenerTestOptions());
try {
// Connect and close.
final Connection connection =
- new LDAPConnectionFactory(listener.getSocketAddress()).getConnection();
+ new LDAPConnectionFactory(listener.getSocketAddress(), getLDAPTestOptions()).
+ getConnection();
assertThat(serverConnection.context.get(10, TimeUnit.SECONDS)).isNotNull();
assertThat(serverConnection.isClosed.getCount()).isEqualTo(1);
connection.close();
@@ -277,13 +305,14 @@
// Connection pool and load balancing tests.
final ConnectionFactory offlineServer1 =
Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
- findFreeSocketAddress()), "offline1");
+ findFreeSocketAddress(), getLDAPTestOptions()), "offline1");
final ConnectionFactory offlineServer2 =
Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
- findFreeSocketAddress()), "offline2");
+ findFreeSocketAddress(), getLDAPTestOptions()), "offline2");
final ConnectionFactory onlineServer =
Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
- onlineServerListener.getSocketAddress()), "online");
+ onlineServerListener.getSocketAddress(), getLDAPTestOptions()),
+ "online");
// Round robin.
final ConnectionFactory loadBalancer =
@@ -345,19 +374,21 @@
final MockServerConnectionFactory onlineServerConnectionFactory =
new MockServerConnectionFactory(onlineServerConnection);
final LDAPListener onlineServerListener =
- new LDAPListener(new InetSocketAddress(0), onlineServerConnectionFactory);
+ new LDAPListener(new InetSocketAddress(0), onlineServerConnectionFactory,
+ getLDAPListenerTestOptions());
try {
// Connection pool and load balancing tests.
final ConnectionFactory offlineServer1 =
Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
- findFreeSocketAddress()), "offline1");
+ findFreeSocketAddress(), getLDAPTestOptions()), "offline1");
final ConnectionFactory offlineServer2 =
Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
- findFreeSocketAddress()), "offline2");
+ findFreeSocketAddress(), getLDAPTestOptions()), "offline2");
final ConnectionFactory onlineServer =
Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
- onlineServerListener.getSocketAddress()), "online");
+ onlineServerListener.getSocketAddress(), getLDAPTestOptions()),
+ "online");
// Round robin.
final ConnectionFactory loadBalancer =
@@ -396,11 +427,13 @@
new MockServerConnectionFactory(proxyServerConnection);
final LDAPListener proxyListener =
- new LDAPListener(new InetSocketAddress(0), proxyServerConnectionFactory);
+ new LDAPListener(new InetSocketAddress(0), proxyServerConnectionFactory,
+ getLDAPListenerTestOptions());
try {
// Connect, bind, and close.
final Connection connection =
- new LDAPConnectionFactory(proxyListener.getSocketAddress()).getConnection();
+ new LDAPConnectionFactory(proxyListener.getSocketAddress(),
+ getLDAPTestOptions()).getConnection();
try {
connection.bind("cn=test", "password".toCharArray());
@@ -447,7 +480,8 @@
final LDAPClientContext clientContext) throws ErrorResultException {
// First attempt offline server.
LDAPConnectionFactory lcf =
- new LDAPConnectionFactory(findFreeSocketAddress());
+ new LDAPConnectionFactory(findFreeSocketAddress(),
+ getLDAPTestOptions());
try {
// This is expected to fail.
lcf.getConnection().close();
@@ -486,7 +520,8 @@
try {
// Connect and close.
final Connection connection =
- new LDAPConnectionFactory(proxyListener.getSocketAddress()).getConnection();
+ new LDAPConnectionFactory(proxyListener.getSocketAddress(), getLDAPTestOptions()).
+ getConnection();
assertThat(proxyServerConnection.context.get(10, TimeUnit.SECONDS)).isNotNull();
assertThat(onlineServerConnection.context.get(10, TimeUnit.SECONDS)).isNotNull();
@@ -516,7 +551,8 @@
final MockServerConnectionFactory onlineServerConnectionFactory =
new MockServerConnectionFactory(onlineServerConnection);
final LDAPListener onlineServerListener =
- new LDAPListener(findFreeSocketAddress(), onlineServerConnectionFactory);
+ new LDAPListener(findFreeSocketAddress(), onlineServerConnectionFactory,
+ getLDAPListenerTestOptions());
try {
final MockServerConnection proxyServerConnection = new MockServerConnection() {
@@ -531,7 +567,8 @@
final ResultHandler<BindResult> resultHandler)
throws UnsupportedOperationException {
// First attempt offline server.
- LDAPConnectionFactory lcf = new LDAPConnectionFactory(findFreeSocketAddress());
+ LDAPConnectionFactory lcf = new LDAPConnectionFactory(findFreeSocketAddress(),
+ getLDAPTestOptions());
try {
// This is expected to fail.
lcf.getConnection().close();
@@ -541,9 +578,8 @@
} catch (final ConnectionException ce) {
// This is expected - so go to online server.
try {
- lcf =
- new LDAPConnectionFactory(onlineServerListener
- .getSocketAddress());
+ lcf = new LDAPConnectionFactory(onlineServerListener.getSocketAddress(),
+ getLDAPTestOptions());
lcf.getConnection().close();
resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
} catch (final Exception e) {
@@ -564,11 +600,14 @@
final MockServerConnectionFactory proxyServerConnectionFactory =
new MockServerConnectionFactory(proxyServerConnection);
final LDAPListener proxyListener =
- new LDAPListener(findFreeSocketAddress(), proxyServerConnectionFactory);
+ new LDAPListener(findFreeSocketAddress(), proxyServerConnectionFactory,
+ TestCaseUtils.getLDAPListenerTestOptions());
try {
// Connect, bind, and close.
final Connection connection =
- new LDAPConnectionFactory(proxyListener.getSocketAddress()).getConnection();
+ new LDAPConnectionFactory(proxyListener.getSocketAddress(),
+ getLDAPTestOptions()).
+ getConnection();
try {
connection.bind("cn=test", "password".toCharArray());
@@ -601,12 +640,14 @@
final MockServerConnection serverConnection = new MockServerConnection();
final MockServerConnectionFactory factory =
new MockServerConnectionFactory(serverConnection);
- final LDAPListenerOptions options = new LDAPListenerOptions().setMaxRequestSize(2048);
+ final LDAPListenerOptions options =
+ TestCaseUtils.getLDAPListenerTestOptions().setMaxRequestSize(2048);
final LDAPListener listener = new LDAPListener(findFreeSocketAddress(), factory, options);
Connection connection = null;
try {
- connection = new LDAPConnectionFactory(listener.getSocketAddress()).getConnection();
+ connection = new LDAPConnectionFactory(listener.getSocketAddress(), getLDAPTestOptions()).
+ getConnection();
// Small request
connection.bind("cn=test", "password".toCharArray());
@@ -658,12 +699,14 @@
final MockServerConnection serverConnection = new MockServerConnection();
final MockServerConnectionFactory factory =
new MockServerConnectionFactory(serverConnection);
- final LDAPListener listener = new LDAPListener(findFreeSocketAddress(), factory);
+ final LDAPListener listener = new LDAPListener(findFreeSocketAddress(), factory,
+ TestCaseUtils.getLDAPListenerTestOptions());
final Connection connection;
try {
// Connect and bind.
- connection = new LDAPConnectionFactory(listener.getSocketAddress()).getConnection();
+ connection = new LDAPConnectionFactory(listener.getSocketAddress(), getLDAPTestOptions()).
+ getConnection();
try {
connection.bind("cn=test", "password".toCharArray());
} catch (final ErrorResultException e) {
@@ -678,7 +721,8 @@
try {
// Connect and bind.
final Connection failedConnection =
- new LDAPConnectionFactory(listener.getSocketAddress()).getConnection();
+ new LDAPConnectionFactory(listener.getSocketAddress(), getLDAPTestOptions()).
+ getConnection();
failedConnection.close();
connection.close();
fail("Connection attempt to closed listener succeeded unexpectedly");
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
index 8ec3cdb..051bb6f 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
@@ -27,6 +27,8 @@
package org.forgerock.opendj.ldap;
+import static org.forgerock.opendj.ldap.TestCaseUtils.*;
+
import static com.forgerock.opendj.ldap.LDAPConstants.TYPE_AUTHENTICATION_SASL;
import java.io.IOException;
@@ -542,8 +544,8 @@
}
sslContext = new SSLContextBuilder().getSSLContext();
listener =
- new LDAPListener(TestCaseUtils.findFreeSocketAddress(), getInstance(),
- new LDAPListenerOptions().setBacklog(4096));
+ new LDAPListener(findFreeSocketAddress(), getInstance(),
+ getLDAPListenerTestOptions().setBacklog(4096));
isRunning = true;
}
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java
index 2a8c3bd..17bd937 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java
@@ -222,4 +222,26 @@
}
return mock;
}
+
+ /**
+ * Returns LDAP options with the parameter {@code LDAPOptions#getClassLoader()} already
+ * set to the test class loader.
+ *
+ * @return LDAPOptions already set with the class loader used by the test.
+ * This is required if the test need to use a transport provider.
+ */
+ public static LDAPOptions getLDAPTestOptions() {
+ return new LDAPOptions().setProviderClassLoader(Thread.currentThread().getContextClassLoader());
+ }
+
+ /**
+ * Returns LDAPListener options with the parameter {@code LDAPListenerOptions#getClassLoader()} already
+ * set to the test class loader.
+ *
+ * @return LDAPListenerOptions already set with the class loader used by the test.
+ * This is required if the test need to use a transport provider.
+ */
+ public static LDAPListenerOptions getLDAPListenerTestOptions() {
+ return new LDAPListenerOptions().setProviderClassLoader(Thread.currentThread().getContextClassLoader());
+ }
}
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java
index 00051cc..45ea5b3 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java
@@ -180,15 +180,23 @@
private final ConsoleApplication app;
+ private LDAPOptions options;
+
public ConnectionFactoryProvider(final ArgumentParser argumentParser,
final ConsoleApplication app) throws ArgumentException {
- this(argumentParser, app, "cn=Directory Manager", 389, false);
+ this(argumentParser, app, "cn=Directory Manager", 389, false, null);
+ }
+
+ public ConnectionFactoryProvider(final ArgumentParser argumentParser,
+ final ConsoleApplication app, final LDAPOptions options) throws ArgumentException {
+ this(argumentParser, app, "cn=Directory Manager", 389, false, options);
}
public ConnectionFactoryProvider(final ArgumentParser argumentParser,
final ConsoleApplication app, final String defaultBindDN, final int defaultPort,
- final boolean alwaysSSL) throws ArgumentException {
+ final boolean alwaysSSL, final LDAPOptions options) throws ArgumentException {
this.app = app;
+ this.options = options == null ? new LDAPOptions() : options;
useSSLArg =
new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL, OPTION_LONG_USE_SSL,
INFO_DESCRIPTION_USE_SSL.get());
@@ -432,13 +440,9 @@
}
if (sslContext != null) {
- final LDAPOptions options =
- new LDAPOptions().setSSLContext(sslContext).setUseStartTLS(
- useStartTLSArg.isPresent());
- connFactory = new LDAPConnectionFactory(hostNameArg.getValue(), port, options);
- } else {
- connFactory = new LDAPConnectionFactory(hostNameArg.getValue(), port);
+ options.setSSLContext(sslContext).setUseStartTLS(useStartTLSArg.isPresent());
}
+ connFactory = new LDAPConnectionFactory(hostNameArg.getValue(), port, options);
}
return connFactory;
}
diff --git a/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java b/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java
index afcc9df..fc206a9 100644
--- a/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java
+++ b/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java
@@ -25,6 +25,8 @@
*/
package com.forgerock.opendj.ldap.tools;
+import static com.forgerock.opendj.ldap.tools.TestCaseUtils.getLDAPTestOptions;
+
import static org.fest.assertions.Assertions.*;
import java.io.File;
@@ -50,7 +52,7 @@
public void init() throws Exception {
MockitoAnnotations.initMocks(this);
argParser = new ArgumentParser("unused", new LocalizableMessageBuilder().toMessage(), false);
- connectionFactoryProvider = new ConnectionFactoryProvider(argParser, app);
+ connectionFactoryProvider = new ConnectionFactoryProvider(argParser, app, getLDAPTestOptions());
}
@Test
diff --git a/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/TestCaseUtils.java b/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/TestCaseUtils.java
new file mode 100644
index 0000000..2ff091e
--- /dev/null
+++ b/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/TestCaseUtils.java
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+
+package com.forgerock.opendj.ldap.tools;
+
+import org.forgerock.opendj.ldap.LDAPOptions;
+
+/**
+ * This class defines some utility functions which can be used by test cases.
+ */
+public final class TestCaseUtils {
+
+ /**
+ * Returns LDAP options with the parameter {@code LDAPOptions#getClassLoader()} already
+ * set to the test class loader.
+ *
+ * @return LDAPOptions already set with the class loader used by the test.
+ * This is required if the test need to use a transport provider.
+ */
+ public static LDAPOptions getLDAPTestOptions() {
+ return new LDAPOptions().setProviderClassLoader(Thread.currentThread().getContextClassLoader());
+ }
+
+}
diff --git a/opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/AdaptersTestCase.java b/opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/AdaptersTestCase.java
index e191124..96146a3 100644
--- a/opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/AdaptersTestCase.java
+++ b/opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/AdaptersTestCase.java
@@ -73,13 +73,13 @@
import org.forgerock.opendj.ldap.responses.WhoAmIExtendedResult;
import org.forgerock.opendj.ldif.ConnectionEntryReader;
import org.forgerock.testng.ForgeRockTestCase;
-
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.forgerock.opendj.adapter.server2x.EmbeddedServerTestCaseUtils.CONFIG_PROPERTIES;
+import static org.forgerock.opendj.adapter.server2x.TestCaseUtils.getLDAPTestOptions;
/**
* This class defines a set of tests for the Adapters.class.
@@ -96,8 +96,9 @@
@DataProvider
public Object[][] anonymousConnectionFactories() {
return new Object[][] {
- { new LDAPConnectionFactory("localhost", Integer.valueOf(CONFIG_PROPERTIES
- .getProperty("listen-port"))) }, { Adapters.newAnonymousConnectionFactory() } };
+ { new LDAPConnectionFactory("localhost", Integer.valueOf(CONFIG_PROPERTIES.getProperty("listen-port")),
+ getLDAPTestOptions()) },
+ { Adapters.newAnonymousConnectionFactory() } };
}
/**
@@ -108,9 +109,11 @@
@DataProvider
public Object[][] rootConnectionFactories() {
return new Object[][] {
- { Connections.newAuthenticatedConnectionFactory(new LDAPConnectionFactory("localhost",
- Integer.valueOf(CONFIG_PROPERTIES.getProperty("listen-port"))), Requests
- .newSimpleBindRequest("cn=directory manager", "password".toCharArray())) },
+ { Connections.newAuthenticatedConnectionFactory(
+ new LDAPConnectionFactory("localhost",
+ Integer.valueOf(CONFIG_PROPERTIES.getProperty("listen-port")),
+ getLDAPTestOptions()),
+ Requests.newSimpleBindRequest("cn=directory manager", "password".toCharArray())) },
{ Adapters.newConnectionFactoryForUser(DN.valueOf("cn=directory manager")) } };
}
@@ -216,7 +219,7 @@
public void testSimpleLDAPConnectionFactorySimpleBind() throws ErrorResultException {
final LDAPConnectionFactory factory =
new LDAPConnectionFactory("localhost", Integer.valueOf(CONFIG_PROPERTIES
- .getProperty("listen-port")));
+ .getProperty("listen-port")), getLDAPTestOptions());
Connection connection = null;
try {
connection = factory.getConnection();
@@ -242,7 +245,7 @@
ErrorResultException {
LDAPConnectionFactory factory =
new LDAPConnectionFactory("localhost", Integer.valueOf(CONFIG_PROPERTIES
- .getProperty("listen-port")));
+ .getProperty("listen-port")), getLDAPTestOptions());
Connection connection = factory.getConnection();
PlainSASLBindRequest request =
@@ -1020,7 +1023,7 @@
// LDAP Connection
final LDAPConnectionFactory factory =
new LDAPConnectionFactory("localhost", Integer.valueOf(CONFIG_PROPERTIES
- .getProperty("listen-port")));
+ .getProperty("listen-port")), getLDAPTestOptions());
Connection connection = null;
connection = factory.getConnection();
connection.bind("cn=Directory Manager", "password".toCharArray());
diff --git a/opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/TestCaseUtils.java b/opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/TestCaseUtils.java
new file mode 100644
index 0000000..e1aaf26
--- /dev/null
+++ b/opendj3/opendj-server2x-adapter/src/test/java/org/forgerock/opendj/adapter/server2x/TestCaseUtils.java
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2013 ForgeRock AS.
+ */
+
+package org.forgerock.opendj.adapter.server2x;
+
+import org.forgerock.opendj.ldap.LDAPOptions;
+
+/**
+ * This class defines some utility functions which can be used by test cases.
+ */
+public final class TestCaseUtils {
+
+ /**
+ * Returns LDAP options with the parameter {@code LDAPOptions#getClassLoader()} already
+ * set to the test class loader.
+ *
+ * @return LDAPOptions already set with the class loader used by the test.
+ * This is required if the test need to use a transport provider.
+ */
+ public static LDAPOptions getLDAPTestOptions() {
+ return new LDAPOptions().setProviderClassLoader(Thread.currentThread().getContextClassLoader());
+ }
+
+}
--
Gitblit v1.10.0