001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2015 ForgeRock AS.
025 */
026package org.forgerock.opendj.ldap.spi;
027
028import java.io.Closeable;
029import java.util.List;
030
031import javax.net.ssl.SSLContext;
032
033import org.forgerock.opendj.ldap.ConnectionEventListener;
034import org.forgerock.opendj.ldap.IntermediateResponseHandler;
035import org.forgerock.opendj.ldap.LdapException;
036import org.forgerock.opendj.ldap.LdapPromise;
037import org.forgerock.opendj.ldap.SearchResultHandler;
038import org.forgerock.opendj.ldap.requests.AbandonRequest;
039import org.forgerock.opendj.ldap.requests.AddRequest;
040import org.forgerock.opendj.ldap.requests.BindRequest;
041import org.forgerock.opendj.ldap.requests.CompareRequest;
042import org.forgerock.opendj.ldap.requests.DeleteRequest;
043import org.forgerock.opendj.ldap.requests.ExtendedRequest;
044import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
045import org.forgerock.opendj.ldap.requests.ModifyRequest;
046import org.forgerock.opendj.ldap.requests.SearchRequest;
047import org.forgerock.opendj.ldap.requests.UnbindRequest;
048import org.forgerock.opendj.ldap.responses.BindResult;
049import org.forgerock.opendj.ldap.responses.CompareResult;
050import org.forgerock.opendj.ldap.responses.ExtendedResult;
051import org.forgerock.opendj.ldap.responses.Result;
052import org.forgerock.util.promise.Promise;
053
054/**
055 * LDAP connection interface which implementations of {@link LDAPConnectionFactoryImpl} should implement.
056 */
057public interface LDAPConnectionImpl extends Closeable {
058
059    /**
060     * Abandons the unfinished operation identified in the provided abandon request.
061     *
062     * @param request
063     *         The request identifying the operation to be abandoned.
064     * @return A promise whose result is Void.
065     * @throws UnsupportedOperationException
066     *         If this connection does not support abandon operations.
067     * @throws IllegalStateException
068     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
069     * @throws NullPointerException
070     *         If {@code request} was {@code null}.
071     * @see org.forgerock.opendj.ldap.Connection#abandonAsync(AbandonRequest)
072     */
073    LdapPromise<Void> abandonAsync(AbandonRequest request);
074
075    /**
076     * Asynchronously adds an entry to the Directory Server using the provided add request.
077     *
078     * @param request
079     *         The add request.
080     * @param intermediateResponseHandler
081     *         An intermediate response handler which can be used to process any intermediate responses as they are
082     *         received, may be {@code null}.
083     * @return A promise representing the result of the operation.
084     * @throws UnsupportedOperationException
085     *         If this connection does not support add operations.
086     * @throws IllegalStateException
087     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
088     * @throws NullPointerException
089     *         If {@code request} was {@code null}.
090     * @see org.forgerock.opendj.ldap.Connection#addAsync(AddRequest, IntermediateResponseHandler)
091     */
092    LdapPromise<Result> addAsync(AddRequest request, IntermediateResponseHandler intermediateResponseHandler);
093
094    /**
095     * Registers the provided connection event listener so that it will be notified when this connection is closed by
096     * the application, receives an unsolicited notification, or experiences a fatal error.
097     *
098     * @param listener
099     *         The listener which wants to be notified when events occur on this connection.
100     * @throws IllegalStateException
101     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
102     * @throws NullPointerException
103     *         If the {@code listener} was {@code null}.
104     * @see org.forgerock.opendj.ldap.Connection#addConnectionEventListener(ConnectionEventListener)
105     */
106    void addConnectionEventListener(ConnectionEventListener listener);
107
108    /**
109     * Asynchronously authenticates to the Directory Server using the provided bind request.
110     *
111     * @param request
112     *         The bind request.
113     * @param intermediateResponseHandler
114     *         An intermediate response handler which can be used to process any intermediate responses as they are
115     *         received, may be {@code null}.
116     * @return A promise representing the result of the operation.
117     * @throws UnsupportedOperationException
118     *         If this connection does not support bind operations.
119     * @throws IllegalStateException
120     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
121     * @throws NullPointerException
122     *         If {@code request} was {@code null}.
123     * @see org.forgerock.opendj.ldap.Connection#bindAsync(BindRequest, IntermediateResponseHandler)
124     */
125    LdapPromise<BindResult> bindAsync(BindRequest request, IntermediateResponseHandler intermediateResponseHandler);
126
127    /**
128     * Releases any resources associated with this connection.
129     * <p/>
130     * Calling {@code close} on a connection that is already closed has no effect.
131     * @see org.forgerock.opendj.ldap.Connection#close()
132     */
133    @Override
134    void close();
135
136    /**
137     * Releases any resources associated with this connection.
138     * <p/>
139     * Calling {@code close} on a connection that is already closed has no effect.
140     *
141     * @param request
142     *         The unbind request to use in the case where a physical connection is closed.
143     * @param reason
144     *         A reason describing why the connection was closed.
145     * @throws NullPointerException
146     *         If {@code request} was {@code null}.
147     * @see org.forgerock.opendj.ldap.Connection#close(UnbindRequest, String)
148     */
149    void close(UnbindRequest request, String reason);
150
151    /**
152     * Asynchronously compares an entry in the Directory Server using the provided compare request.
153     *
154     * @param request
155     *         The compare request.
156     * @param intermediateResponseHandler
157     *         An intermediate response handler which can be used to process any intermediate responses as they are
158     *         received, may be {@code null}.
159     * @return A promise representing the result of the operation.
160     * @throws UnsupportedOperationException
161     *         If this connection does not support compare operations.
162     * @throws IllegalStateException
163     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
164     * @throws NullPointerException
165     *         If {@code request} was {@code null}.
166     * @see org.forgerock.opendj.ldap.Connection#compareAsync(CompareRequest, IntermediateResponseHandler)
167     */
168    LdapPromise<CompareResult> compareAsync(
169            CompareRequest request, IntermediateResponseHandler intermediateResponseHandler);
170
171    /**
172     * Asynchronously deletes an entry from the Directory Server using the provided delete request.
173     *
174     * @param request
175     *         The delete request.
176     * @param intermediateResponseHandler
177     *         An intermediate response handler which can be used to process any intermediate responses as they are
178     *         received, may be {@code null}.
179     * @return A promise representing the result of the operation.
180     * @throws UnsupportedOperationException
181     *         If this connection does not support delete operations.
182     * @throws IllegalStateException
183     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
184     * @throws NullPointerException
185     *         If {@code request} was {@code null}.
186     * @see org.forgerock.opendj.ldap.Connection#deleteAsync(DeleteRequest, IntermediateResponseHandler)
187     */
188    LdapPromise<Result> deleteAsync(DeleteRequest request, IntermediateResponseHandler intermediateResponseHandler);
189
190    /**
191     * Installs the TLS/SSL security layer on the underlying connection. The TLS/SSL security layer will be installed
192     * beneath any existing connection security layers and can only be installed at most once.
193     *
194     * @param sslContext
195     *         The {@code SSLContext} which should be used to secure the
196     * @param protocols
197     *         Names of all the protocols to enable or {@code null} to use the default protocols.
198     * @param suites
199     *         Names of all the suites to enable or {@code null} to use the default cipher suites.
200     * @return A promise which will complete once the SSL handshake has completed.
201     * @throws IllegalStateException
202     *         If the TLS/SSL security layer has already been installed.
203     */
204    Promise<Void, LdapException> enableTLS(SSLContext sslContext, List<String> protocols, List<String> suites);
205
206    /**
207     * Asynchronously performs the provided extended request in the Directory Server.
208     *
209     * @param <R>
210     *         The type of result returned by the extended request.
211     * @param request
212     *         The extended request.
213     * @param intermediateResponseHandler
214     *         An intermediate response handler which can be used to process any intermediate responses as they are
215     *         received, may be {@code null}.
216     * @return A promise representing the result of the operation.
217     * @throws UnsupportedOperationException
218     *         If this connection does not support extended operations.
219     * @throws IllegalStateException
220     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
221     * @throws NullPointerException
222     *         If {@code request} was {@code null}.
223     * @see org.forgerock.opendj.ldap.Connection#extendedRequestAsync(ExtendedRequest, IntermediateResponseHandler)
224     */
225    <R extends ExtendedResult> LdapPromise<R> extendedRequestAsync(
226            ExtendedRequest<R> request, IntermediateResponseHandler intermediateResponseHandler);
227
228    /**
229     * Indicates whether or not this connection has been explicitly closed by calling {@code close}. This method will
230     * not return {@code true} if a fatal error has occurred on the connection unless {@code close} has been called.
231     *
232     * @return {@code true} if this connection has been explicitly closed by calling {@code close}, or {@code false}
233     * otherwise.
234     * @see org.forgerock.opendj.ldap.Connection#isClosed()
235     */
236    boolean isClosed();
237
238    /**
239     * Returns {@code true} if this connection has not been closed and no fatal errors have been detected. This method
240     * is guaranteed to return {@code false} only when it is called after the method {@code close} has been called.
241     *
242     * @return {@code true} if this connection is valid, {@code false} otherwise.
243     * @see org.forgerock.opendj.ldap.Connection#isValid()
244     */
245    boolean isValid();
246
247    /**
248     * Asynchronously modifies an entry in the Directory Server using the provided modify request.
249     *
250     * @param request
251     *         The modify request.
252     * @param intermediateResponseHandler
253     *         An intermediate response handler which can be used to process any intermediate responses as they are
254     *         received, may be {@code null}.
255     * @return A promise representing the result of the operation.
256     * @throws UnsupportedOperationException
257     *         If this connection does not support modify operations.
258     * @throws IllegalStateException
259     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
260     * @throws NullPointerException
261     *         If {@code request} was {@code null}.
262     * @see org.forgerock.opendj.ldap.Connection#modifyAsync(ModifyRequest, IntermediateResponseHandler)
263     */
264    LdapPromise<Result> modifyAsync(ModifyRequest request, IntermediateResponseHandler intermediateResponseHandler);
265
266    /**
267     * Asynchronously renames an entry in the Directory Server using the provided modify DN request.
268     *
269     * @param request
270     *         The modify DN request.
271     * @param intermediateResponseHandler
272     *         An intermediate response handler which can be used to process any intermediate responses as they are
273     *         received, may be {@code null}.
274     * @return A promise representing the result of the operation.
275     * @throws UnsupportedOperationException
276     *         If this connection does not support modify DN operations.
277     * @throws IllegalStateException
278     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
279     * @throws NullPointerException
280     *         If {@code request} was {@code null}.
281     * @see org.forgerock.opendj.ldap.Connection#modifyDNAsync(ModifyDNRequest, IntermediateResponseHandler)
282     */
283    LdapPromise<Result> modifyDNAsync(
284            ModifyDNRequest request, IntermediateResponseHandler intermediateResponseHandler);
285
286    /**
287     * Removes the provided connection event listener from this connection so that it will no longer be notified when
288     * this connection is closed by the application, receives an unsolicited notification, or experiences a fatal
289     * error.
290     *
291     * @param listener
292     *         The listener which no longer wants to be notified when events occur on this connection.
293     * @throws NullPointerException
294     *         If the {@code listener} was {@code null}.
295     * @see org.forgerock.opendj.ldap.Connection#removeConnectionEventListener(ConnectionEventListener)
296     */
297    void removeConnectionEventListener(ConnectionEventListener listener);
298
299    /**
300     * Asynchronously searches the Directory Server using the provided search request.
301     *
302     * @param request
303     *         The search request.
304     * @param intermediateResponseHandler
305     *         An intermediate response handler which can be used to process any intermediate responses as they are
306     *         received, may be {@code null}.
307     * @param entryHandler
308     *         A search result handler which can be used to asynchronously process the search result entries and
309     *         references as they are received, may be {@code null}.
310     * @return A promise representing the result of the operation.
311     * @throws UnsupportedOperationException
312     *         If this connection does not support search operations.
313     * @throws IllegalStateException
314     *         If this connection has already been closed, i.e. if {@code isClosed() == true}.
315     * @throws NullPointerException
316     *         If {@code request} was {@code null}.
317     * @see org.forgerock.opendj.ldap.Connection#searchAsync(SearchRequest, IntermediateResponseHandler,
318     * SearchResultHandler)
319     */
320    LdapPromise<Result> searchAsync(
321            SearchRequest request,
322            IntermediateResponseHandler intermediateResponseHandler,
323            SearchResultHandler entryHandler);
324}