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
* LDAPConnectionFactory/LDAPListener load its implementation via java.util.ServiceLoader, the JDK loader facility.
An implementation is given by a transport provider.
Common code to load a provider is implemented in StaticUtils#getProvider
* New package org.forgerock.opendj.ldap.spi that contains interfaces for providers and implementations.
TransportProvider interface which provides:
- LDAPConnectionFactoryImpl, implementation for LDAPConnectionFactory
- LDAPListenerImpl, implementation for LDAPListener
* There is one transport provider based on Grizzly: GrizzlyTransportProvider class which provides the two implementation classes
- GrizzlyLDAPConnectionFactory
- GrizzlyLDAPListener
In order to locate transport provider to use, the file 'org.forgerock.opendj.ldap.spi.TransportProvider'
must be available in the classpath in META-INF/services directory.
That file is included with the value "com.forgerock.opendj.ldap.GrizzlyTransportProvider" to have Grizzly as the default provider
* LDAPOptions and LDAPListenerOptions:
- have no more TCPNIOTransport option,
- have two new options transportProvider and providerClassLoader to tune loading of providers.
- transportProvider allow to require a given provider (eg, "Grizzly"), otherwise the first provider found will be used.
- providerClassLoader allow to provide a class loader to use when several class loaders are used by an application.
ServiceLoader needs to load both provider-configuration file and provider class from the same class loader,
so there are case where you must provide the correct class loader to find the provider class.
* Fixed all the tests in opendj-ldap-sdk, because they suffer from the class loader problem if not providing the right class loader
- Systematically provide the class loader used by test class when creating LDAPConnectionFactory or LDAPListener
- Added utility methods in TestCaseUtils class to ease the use of custom class loader
* Fixed tests in modules: opendj-ldap-toolkit and opendj-server2x-adapter
- Same fix than for opendj-ldap-sdk
- Added new TestCaseUtils.java class in both modules to hold utility methods
10 files added
4 files renamed
16 files modified
| File was renamed from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java |
| | |
| | | /** |
| | | * 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 |
| | |
| | | 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(); |
| | |
| | | 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; |
| | | } |
| File was renamed from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java |
| | |
| | | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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. |
| | |
| | | @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) { |
| | |
| | | // 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; |
| | |
| | | } |
| | | } |
| | | |
| | | 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. |
| | |
| | | .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. |
| | | * |
| | |
| | | * @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 |
| File was renamed from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPListenerImpl.java |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | * 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()); |
| | |
| | | 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()); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 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(); |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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"; |
| | | } |
| | | |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2012 ForgeRock AS. |
| | | * Portions copyright 2012-2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package com.forgerock.opendj.ldap; |
| | |
| | | * 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"); |
| | |
| | | @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 = |
| | |
| | | @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 = |
| | |
| | | @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 = |
| | |
| | | @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 = |
| | |
| | | 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) { |
| | |
| | | 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 = |
| | |
| | | @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 = |
| | |
| | | @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 = |
| | |
| | | @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 = |
| | |
| | | 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 = |
| | |
| | | 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 = |
| | |
| | | |
| | | // 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()); |
| | |
| | | // 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) { |
| | |
| | | @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); |
| | |
| | | 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()); |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | private final LDAPReader ldapReader; |
| | | private final LDAPListenerImpl listener; |
| | | private final GrizzlyLDAPListener listener; |
| | | private final int maxASN1ElementSize; |
| | | |
| | | private final AbstractLDAPMessageHandler<FilterChainContext> serverRequestHandler = |
| | |
| | | } |
| | | }; |
| | | |
| | | LDAPServerFilter(final LDAPListenerImpl listener, final LDAPReader ldapReader, |
| | | LDAPServerFilter(final GrizzlyLDAPListener listener, final LDAPReader ldapReader, |
| | | final int maxASN1ElementSize) { |
| | | this.listener = listener; |
| | | this.ldapReader = ldapReader; |
| | |
| | | * 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. |
| | |
| | | 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. |
| | |
| | | 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. |
| | | } |
| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | |
| | | // 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())); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | 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; |
| | | |
| | | /** |
| | |
| | | */ |
| | | 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. |
| | |
| | | * 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()); |
| | |
| | | * 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); |
| | | } |
| | | |
| | | /** |
| | |
| | | * 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()); |
| | |
| | | * 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); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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(); |
| | |
| | | |
| | | 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; |
| | | |
| | | /** |
| | |
| | | * </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. |
| | |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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() { |
| | |
| | | * |
| | | * |
| | | * 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; |
| | | |
| | | /** |
| | |
| | | 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2012 ForgeRock AS. |
| | | * Portions copyright 2012-2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | |
| | | import org.glassfish.grizzly.nio.transport.TCPNIOTransport; |
| | | |
| | | import com.forgerock.opendj.util.Validator; |
| | | |
| | | /** |
| | |
| | | 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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(); |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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(); |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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(); |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | |
| New file |
| | |
| | | # |
| | | # 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 |
| File was renamed from opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/ldap/LDAPConnectionTestCase.java |
| | |
| | | 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; |
| | |
| | | * 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. |
| | |
| | | @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=*)"); |
| | |
| | | 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; |
| | |
| | | |
| | | 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); |
| | |
| | | // 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", |
| | |
| | | |
| | | // 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); |
| | |
| | | } |
| | | }); |
| | | |
| | | 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; |
| | |
| | | } |
| | | }); |
| | | |
| | | 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 { |
| | |
| | | final ConnectionFactory factory = |
| | | newLoadBalancer(new FailoverLoadBalancingAlgorithm(asList(newFixedConnectionPool( |
| | | newHeartBeatConnectionFactory(new LDAPConnectionFactory( |
| | | getServerSocketAddress())), 2)))); |
| | | getServerSocketAddress(), getLDAPTestOptions())), 2)))); |
| | | Connection conn = null; |
| | | try { |
| | | conn = factory.getConnection(); |
| | |
| | | |
| | | 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; |
| | |
| | | // 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. |
| | |
| | | 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. |
| | |
| | | latch.release(); |
| | | return mock(ServerConnection.class); |
| | | } |
| | | }); |
| | | }, |
| | | TestCaseUtils.getLDAPListenerTestOptions()); |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | 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(); |
| | |
| | | // 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 = |
| | |
| | | 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 = |
| | |
| | | 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()); |
| | | |
| | |
| | | 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(); |
| | |
| | | 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(); |
| | |
| | | final MockServerConnectionFactory onlineServerConnectionFactory = |
| | | new MockServerConnectionFactory(onlineServerConnection); |
| | | final LDAPListener onlineServerListener = |
| | | new LDAPListener(findFreeSocketAddress(), onlineServerConnectionFactory); |
| | | new LDAPListener(findFreeSocketAddress(), onlineServerConnectionFactory, |
| | | getLDAPListenerTestOptions()); |
| | | |
| | | try { |
| | | final MockServerConnection proxyServerConnection = new MockServerConnection() { |
| | |
| | | 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(); |
| | |
| | | } 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) { |
| | |
| | | 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()); |
| | | |
| | |
| | | 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()); |
| | |
| | | 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) { |
| | |
| | | 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"); |
| | |
| | | |
| | | 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; |
| | |
| | | } |
| | | sslContext = new SSLContextBuilder().getSSLContext(); |
| | | listener = |
| | | new LDAPListener(TestCaseUtils.findFreeSocketAddress(), getInstance(), |
| | | new LDAPListenerOptions().setBacklog(4096)); |
| | | new LDAPListener(findFreeSocketAddress(), getInstance(), |
| | | getLDAPListenerTestOptions().setBacklog(4096)); |
| | | isRunning = true; |
| | | } |
| | | |
| | |
| | | } |
| | | 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()); |
| | | } |
| | | } |
| | |
| | | |
| | | 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()); |
| | |
| | | } |
| | | |
| | | 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; |
| | | } |
| | |
| | | */ |
| | | 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; |
| | |
| | | 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 |
| New file |
| | |
| | | /* |
| | | * 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()); |
| | | } |
| | | |
| | | } |
| | |
| | | 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. |
| | |
| | | @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() } }; |
| | | } |
| | | |
| | | /** |
| | |
| | | @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")) } }; |
| | | } |
| | | |
| | |
| | | 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(); |
| | |
| | | ErrorResultException { |
| | | LDAPConnectionFactory factory = |
| | | new LDAPConnectionFactory("localhost", Integer.valueOf(CONFIG_PROPERTIES |
| | | .getProperty("listen-port"))); |
| | | .getProperty("listen-port")), getLDAPTestOptions()); |
| | | |
| | | Connection connection = factory.getConnection(); |
| | | PlainSASLBindRequest request = |
| | |
| | | // 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()); |
| New file |
| | |
| | | /* |
| | | * 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()); |
| | | } |
| | | |
| | | } |