Commit from OpenDS, matthew_swift
* add unit tests for ConnectionEventListeners.
* make HeartBeatConnectionFactory use ScheduledExecutors.
* add AsynchronousConnectionDecorator base implementation to avoid re-implementing delegate methods each time.
1 files deleted
1 files added
8 files modified
| | |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.requests.*; |
| | | import org.opends.sdk.responses.*; |
| | | import org.opends.sdk.schema.Schema; |
| | | import org.opends.sdk.requests.BindRequest; |
| | | import org.opends.sdk.responses.BindResult; |
| | | |
| | | import com.sun.opends.sdk.util.AsynchronousConnectionDecorator; |
| | | import com.sun.opends.sdk.util.FutureResultTransformer; |
| | | import com.sun.opends.sdk.util.RecursiveFutureResult; |
| | | import com.sun.opends.sdk.util.Validator; |
| | |
| | | * An authenticated asynchronous connection supports all operations except |
| | | * Bind operations. |
| | | */ |
| | | public static final class AuthenticatedAsynchronousConnection implements |
| | | AsynchronousConnection |
| | | public static final class AuthenticatedAsynchronousConnection extends |
| | | AsynchronousConnectionDecorator |
| | | { |
| | | |
| | | private final BindRequest request; |
| | | |
| | | private volatile BindResult result; |
| | | |
| | | private final AsynchronousConnection connection; |
| | | |
| | | |
| | | |
| | | private AuthenticatedAsynchronousConnection( |
| | | final AsynchronousConnection connection, final BindRequest request, |
| | | final BindResult result) |
| | | { |
| | | this.connection = connection; |
| | | super(connection); |
| | | this.request = request; |
| | | this.result = result; |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Void> abandon(final AbandonRequest request) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.abandon(request); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> add(final AddRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.add(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> add(final AddRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection |
| | | .add(request, resultHandler, intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void addConnectionEventListener( |
| | | final ConnectionEventListener listener) throws IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | connection.addConnectionEventListener(listener); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Bind operations are not supported by pre-authenticated connections. This |
| | | * method will always throw {@code UnsupportedOperationException}. |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Bind operations are not supported by pre-authenticated connections. This |
| | | * method will always throw {@code UnsupportedOperationException}. |
| | | */ |
| | | public FutureResult<BindResult> bind(final BindRequest request, |
| | | final ResultHandler<? super BindResult> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.bind(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void close() |
| | | { |
| | | connection.close(); |
| | | } |
| | | |
| | | |
| | | |
| | | public void close(final UnbindRequest request, final String reason) |
| | | throws NullPointerException |
| | | { |
| | | connection.close(request, reason); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<CompareResult> compare(final CompareRequest request, |
| | | final ResultHandler<? super CompareResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<CompareResult> compare(final CompareRequest request, |
| | | final ResultHandler<? super CompareResult> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> delete(final DeleteRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> delete(final DeleteRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | final ExtendedRequest<R> request, final ResultHandler<? super R> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | final ExtendedRequest<R> request, |
| | | final ResultHandler<? super R> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Connection getSynchronousConnection() |
| | | { |
| | | return new SynchronousConnection(connection); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isClosed() |
| | | { |
| | | return connection.isClosed(); |
| | | } |
| | | |
| | | |
| | | |
| | | public boolean isValid() |
| | | { |
| | | return connection.isValid(); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modify(final ModifyRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modify(final ModifyRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modifyDN(final ModifyDNRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modifyDN(final ModifyDNRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<SearchResultEntry> readEntry(final DN name, |
| | | final Collection<String> attributeDescriptions, |
| | | final ResultHandler<? super SearchResultEntry> resultHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.readEntry(name, attributeDescriptions, resultHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<RootDSE> readRootDSE( |
| | | final ResultHandler<? super RootDSE> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readRootDSE(handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<Schema> readSchema(final DN name, |
| | | final ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchema(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<Schema> readSchemaForEntry(final DN name, |
| | | final ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchemaForEntry(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Re-authenticates to the Directory Server using the bind request |
| | | * associated with this connection. If re-authentication fails for some |
| | | * reason then this connection will be automatically closed. |
| | |
| | | |
| | | |
| | | |
| | | public void removeConnectionEventListener( |
| | | final ConnectionEventListener listener) throws NullPointerException |
| | | { |
| | | connection.removeConnectionEventListener(listener); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> search(final SearchRequest request, |
| | | final SearchResultHandler handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.search(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> search(final SearchRequest request, |
| | | final SearchResultHandler resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.search(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<SearchResultEntry> searchSingleEntry( |
| | | final SearchRequest request, |
| | | final ResultHandler<? super SearchResultEntry> resultHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.searchSingleEntry(request, resultHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * 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 |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package com.sun.opends.sdk.util; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.opends.sdk.*; |
| | | import org.opends.sdk.requests.*; |
| | | import org.opends.sdk.responses.*; |
| | | import org.opends.sdk.schema.Schema; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A base class from which asynchronous connection decorators may be easily |
| | | * implemented. The default implementation of each method is to delegate to the |
| | | * decorated connection. |
| | | */ |
| | | public abstract class AsynchronousConnectionDecorator implements |
| | | AsynchronousConnection |
| | | { |
| | | /** |
| | | * The decorated asynchronous connection. |
| | | */ |
| | | protected final AsynchronousConnection connection; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new asynchronous connection decorator. |
| | | * |
| | | * @param connection |
| | | * The asynchronous connection to be decorated. |
| | | */ |
| | | protected AsynchronousConnectionDecorator(AsynchronousConnection connection) |
| | | { |
| | | Validator.ensureNotNull(connection); |
| | | this.connection = connection; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Void> abandon(AbandonRequest request) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.abandon(request); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> add(AddRequest request, |
| | | ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.add(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> add(AddRequest request, |
| | | ResultHandler<? super Result> resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.add(request, resultHandler, intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public void addConnectionEventListener(ConnectionEventListener listener) |
| | | throws IllegalStateException, NullPointerException |
| | | { |
| | | connection.addConnectionEventListener(listener); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<BindResult> bind(BindRequest request, |
| | | ResultHandler<? super BindResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.bind(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<BindResult> bind(BindRequest request, |
| | | ResultHandler<? super BindResult> resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.bind(request, resultHandler, intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public void close() |
| | | { |
| | | connection.close(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public void close(UnbindRequest request, String reason) |
| | | throws NullPointerException |
| | | { |
| | | connection.close(request, reason); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<CompareResult> compare(CompareRequest request, |
| | | ResultHandler<? super CompareResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<CompareResult> compare(CompareRequest request, |
| | | ResultHandler<? super CompareResult> resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> delete(DeleteRequest request, |
| | | ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> delete(DeleteRequest request, |
| | | ResultHandler<? super Result> resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | ExtendedRequest<R> request, ResultHandler<? super R> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | ExtendedRequest<R> request, ResultHandler<? super R> resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to return a synchronous view of this |
| | | * decorated connection. |
| | | */ |
| | | public Connection getSynchronousConnection() |
| | | { |
| | | return new SynchronousConnection(this); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public boolean isClosed() |
| | | { |
| | | return connection.isClosed(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public boolean isValid() |
| | | { |
| | | return connection.isValid(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> modify(ModifyRequest request, |
| | | ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> modify(ModifyRequest request, |
| | | ResultHandler<? super Result> resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> modifyDN(ModifyDNRequest request, |
| | | ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> modifyDN(ModifyDNRequest request, |
| | | ResultHandler<? super Result> resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<SearchResultEntry> readEntry(DN name, |
| | | Collection<String> attributeDescriptions, |
| | | ResultHandler<? super SearchResultEntry> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.readEntry(name, attributeDescriptions, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<RootDSE> readRootDSE( |
| | | ResultHandler<? super RootDSE> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readRootDSE(handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Schema> readSchema(DN name, |
| | | ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchema(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Schema> readSchemaForEntry(DN name, |
| | | ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchemaForEntry(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public void removeConnectionEventListener(ConnectionEventListener listener) |
| | | throws NullPointerException |
| | | { |
| | | connection.removeConnectionEventListener(listener); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> search(SearchRequest request, |
| | | SearchResultHandler handler) throws UnsupportedOperationException, |
| | | IllegalStateException, NullPointerException |
| | | { |
| | | return connection.search(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<Result> search(SearchRequest request, |
| | | SearchResultHandler resultHandler, |
| | | IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.search(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public FutureResult<SearchResultEntry> searchSingleEntry( |
| | | SearchRequest request, ResultHandler<? super SearchResultEntry> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.searchSingleEntry(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * The default implementation is to delegate. |
| | | */ |
| | | public String toString() |
| | | { |
| | | return connection.toString(); |
| | | } |
| | | |
| | | } |
| | |
| | | { |
| | | // Enable monitoring. |
| | | monitoringFuture = scheduler.scheduleWithFixedDelay( |
| | | new MonitorThread(), 0, monitoringInterval, |
| | | new MonitorRunnable(), 0, monitoringInterval, |
| | | monitoringIntervalTimeUnit); |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | private final class MonitorThread implements Runnable |
| | | private final class MonitorRunnable implements Runnable |
| | | { |
| | | private MonitorThread() |
| | | private MonitorRunnable() |
| | | { |
| | | // Nothing to do. |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new abstract load balancing algorithm. |
| | | * Creates a new abstract load balancing algorithm which will monitor offline |
| | | * connection factories every 10 seconds using the default scheduler. |
| | | * |
| | | * @param factories |
| | | * The connection factories. |
| | | */ |
| | | AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories) |
| | | { |
| | | this(factories, StaticUtils.getDefaultScheduler()); |
| | | this(factories, 10, TimeUnit.SECONDS, StaticUtils.getDefaultScheduler()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new abstract load balancing algorithm. |
| | | * Creates a new abstract load balancing algorithm which will monitor offline |
| | | * connection factories using the specified frequency using the default |
| | | * scheduler. |
| | | * |
| | | * @param factories |
| | | * The connection factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring dead |
| | | * connection factories to see if they are usable again. |
| | | */ |
| | | AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories, |
| | | final ScheduledExecutorService scheduler) |
| | | { |
| | | this(factories, StaticUtils.getDefaultScheduler(), 10, TimeUnit.SECONDS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new abstract load balancing algorithm. |
| | | * |
| | | * @param factories |
| | | * The connection factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring dead |
| | | * connection factories to see if they are usable again. |
| | | * @param interval |
| | | * The interval between attempts to poll offline factories. |
| | | * @param unit |
| | |
| | | * factories. |
| | | */ |
| | | AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories, |
| | | final ScheduledExecutorService scheduler, final long interval, |
| | | final TimeUnit unit) |
| | | final long interval, final TimeUnit unit) |
| | | { |
| | | this(factories, interval, unit, StaticUtils.getDefaultScheduler()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new abstract load balancing algorithm which will monitor offline |
| | | * connection factories using the specified frequency and scheduler. |
| | | * |
| | | * @param factories |
| | | * The connection factories. |
| | | * @param interval |
| | | * The interval between attempts to poll offline factories. |
| | | * @param unit |
| | | * The time unit for the interval between attempts to poll offline |
| | | * factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring dead |
| | | * connection factories to see if they are usable again. |
| | | */ |
| | | AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories, |
| | | final long interval, final TimeUnit unit, |
| | | final ScheduledExecutorService scheduler) |
| | | { |
| | | Validator.ensureNotNull(factories, scheduler, unit); |
| | | |
| | |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import org.opends.sdk.requests.BindRequest; |
| | | import org.opends.sdk.responses.BindResult; |
| | | |
| | | import org.opends.sdk.requests.*; |
| | | import org.opends.sdk.responses.*; |
| | | import org.opends.sdk.schema.Schema; |
| | | |
| | | import com.sun.opends.sdk.util.AsynchronousConnectionDecorator; |
| | | import com.sun.opends.sdk.util.FutureResultTransformer; |
| | | import com.sun.opends.sdk.util.RecursiveFutureResult; |
| | | |
| | |
| | | * An authenticated asynchronous connection supports all operations except |
| | | * Bind operations. |
| | | */ |
| | | public static final class AuthenticatedAsynchronousConnection implements |
| | | AsynchronousConnection |
| | | public static final class AuthenticatedAsynchronousConnection extends |
| | | AsynchronousConnectionDecorator |
| | | { |
| | | |
| | | private final AsynchronousConnection connection; |
| | | |
| | | |
| | | |
| | | private AuthenticatedAsynchronousConnection( |
| | | final AsynchronousConnection connection) |
| | | { |
| | | this.connection = connection; |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Void> abandon(final AbandonRequest request) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.abandon(request); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> add(final AddRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.add(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> add(final AddRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection |
| | | .add(request, resultHandler, intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void addConnectionEventListener( |
| | | final ConnectionEventListener listener) throws IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | connection.addConnectionEventListener(listener); |
| | | super(connection); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Bind operations are not supported by pre-authenticated connections. This |
| | | * method will always throw {@code UnsupportedOperationException}. |
| | | */ |
| | | public FutureResult<BindResult> bind(final BindRequest request, |
| | | final ResultHandler<? super BindResult> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.bind(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void close() |
| | | { |
| | | connection.close(); |
| | | } |
| | | |
| | | |
| | | |
| | | public void close(final UnbindRequest request, final String reason) |
| | | throws NullPointerException |
| | | { |
| | | connection.close(request, reason); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<CompareResult> compare(final CompareRequest request, |
| | | final ResultHandler<? super CompareResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<CompareResult> compare(final CompareRequest request, |
| | | final ResultHandler<? super CompareResult> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> delete(final DeleteRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> delete(final DeleteRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | final ExtendedRequest<R> request, final ResultHandler<? super R> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | final ExtendedRequest<R> request, |
| | | final ResultHandler<? super R> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Connection getSynchronousConnection() |
| | | { |
| | | return new SynchronousConnection(this); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isClosed() |
| | | { |
| | | return connection.isClosed(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isValid() |
| | | { |
| | | return connection.isValid(); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modify(final ModifyRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modify(final ModifyRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modifyDN(final ModifyDNRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modifyDN(final ModifyDNRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<SearchResultEntry> readEntry(final DN name, |
| | | final Collection<String> attributeDescriptions, |
| | | final ResultHandler<? super SearchResultEntry> resultHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.readEntry(name, attributeDescriptions, resultHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<RootDSE> readRootDSE( |
| | | final ResultHandler<? super RootDSE> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readRootDSE(handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<Schema> readSchema(final DN name, |
| | | final ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchema(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<Schema> readSchemaForEntry(final DN name, |
| | | final ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchemaForEntry(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void removeConnectionEventListener( |
| | | final ConnectionEventListener listener) throws NullPointerException |
| | | { |
| | | connection.removeConnectionEventListener(listener); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> search(final SearchRequest request, |
| | | final SearchResultHandler handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.search(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> search(final SearchRequest request, |
| | | final SearchResultHandler resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.search(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<SearchResultEntry> searchSingleEntry( |
| | | final SearchRequest request, |
| | | final ResultHandler<? super SearchResultEntry> resultHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.searchSingleEntry(request, resultHandler); |
| | | throw new UnsupportedOperationException(); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import org.opends.sdk.requests.BindRequest; |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new connection factory which will create connections using the |
| | | * provided connection factory and periodically probe any created connections |
| | | * in order to detect that they are still alive. |
| | | * Creates a new heart-beat connection factory which will create connections |
| | | * using the provided connection factory and periodically ping any created |
| | | * connections in order to detect that they are still alive every 10 seconds |
| | | * using the default scheduler. |
| | | * |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param timeout |
| | | * The time to wait between keep-alive probes. |
| | | * @param unit |
| | | * The time unit of the timeout argument. |
| | | * @return The new heart-beat connection factory. |
| | | * @throws IllegalArgumentException |
| | | * If {@code timeout} was negative. |
| | | * @throws NullPointerException |
| | | * If {@code factory} or {@code unit} was {@code null}. |
| | | * If {@code factory} was {@code null}. |
| | | */ |
| | | public static ConnectionFactory newHeartBeatConnectionFactory( |
| | | final ConnectionFactory factory, final long timeout, final TimeUnit unit) |
| | | throws IllegalArgumentException, NullPointerException |
| | | final ConnectionFactory factory) throws NullPointerException |
| | | { |
| | | Validator.ensureNotNull(factory, unit); |
| | | Validator.ensureTrue(timeout >= 0, "negative timeout"); |
| | | |
| | | return new HeartBeatConnectionFactory(factory, timeout, unit); |
| | | return new HeartBeatConnectionFactory(factory); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new connection factory which will create connections using the |
| | | * provided connection factory and periodically probe any created connections |
| | | * using the specified search request in order to detect that they are still |
| | | * alive. |
| | | * Creates a new heart-beat connection factory which will create connections |
| | | * using the provided connection factory and periodically ping any created |
| | | * connections in order to detect that they are still alive using the |
| | | * specified frequency and the default scheduler. |
| | | * |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param timeout |
| | | * The time to wait between keep-alive probes. |
| | | * @param interval |
| | | * The interval between keepalive pings. |
| | | * @param unit |
| | | * The time unit of the timeout argument. |
| | | * @param heartBeat |
| | | * The search request to use when pinging connections. |
| | | * The time unit for the interval between keepalive pings. |
| | | * @return The new heart-beat connection factory. |
| | | * @throws IllegalArgumentException |
| | | * If {@code timeout} was negative. |
| | | * If {@code interval} was negative. |
| | | * @throws NullPointerException |
| | | * If {@code factory} or {@code unit} was {@code null}. |
| | | */ |
| | | public static ConnectionFactory newHeartBeatConnectionFactory( |
| | | final ConnectionFactory factory, final long interval, final TimeUnit unit) |
| | | throws IllegalArgumentException, NullPointerException |
| | | { |
| | | return new HeartBeatConnectionFactory(factory, interval, unit); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new heart-beat connection factory which will create connections |
| | | * using the provided connection factory and periodically ping any created |
| | | * connections using the specified search request in order to detect that they |
| | | * are still alive. |
| | | * |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param interval |
| | | * The interval between keepalive pings. |
| | | * @param unit |
| | | * The time unit for the interval between keepalive pings. |
| | | * @param heartBeat |
| | | * The search request to use for keepalive pings. |
| | | * @return The new heart-beat connection factory. |
| | | * @throws IllegalArgumentException |
| | | * If {@code interval} was negative. |
| | | * @throws NullPointerException |
| | | * If {@code factory}, {@code unit}, or {@code heartBeat} was {@code null}. |
| | | */ |
| | | public static ConnectionFactory newHeartBeatConnectionFactory( |
| | | final ConnectionFactory factory, final long interval, final TimeUnit unit, |
| | | final SearchRequest heartBeat) throws IllegalArgumentException, |
| | | NullPointerException |
| | | { |
| | | return new HeartBeatConnectionFactory(factory, interval, unit, heartBeat); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new heart-beat connection factory which will create connections |
| | | * using the provided connection factory and periodically ping any created |
| | | * connections using the specified search request in order to detect that they |
| | | * are still alive. |
| | | * |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param interval |
| | | * The interval between keepalive pings. |
| | | * @param unit |
| | | * The time unit for the interval between keepalive pings. |
| | | * @param heartBeat |
| | | * The search request to use for keepalive pings. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically sending keepalive |
| | | * pings. |
| | | * @return The new heart-beat connection factory. |
| | | * @throws IllegalArgumentException |
| | | * If {@code interval} was negative. |
| | | * @throws NullPointerException |
| | | * If {@code factory}, {@code unit}, or {@code heartBeat} was |
| | | * {@code null}. |
| | | */ |
| | | public static ConnectionFactory newHeartBeatConnectionFactory( |
| | | final ConnectionFactory factory, final long timeout, final TimeUnit unit, |
| | | final SearchRequest heartBeat) throws IllegalArgumentException, |
| | | NullPointerException |
| | | final ConnectionFactory factory, final long interval, |
| | | final TimeUnit unit, final SearchRequest heartBeat, |
| | | final ScheduledExecutorService scheduler) |
| | | throws IllegalArgumentException, NullPointerException |
| | | { |
| | | Validator.ensureNotNull(factory, unit, heartBeat); |
| | | Validator.ensureTrue(timeout >= 0, "negative timeout"); |
| | | |
| | | return new HeartBeatConnectionFactory(factory, timeout, unit, heartBeat); |
| | | return new HeartBeatConnectionFactory(factory, interval, unit, heartBeat, |
| | | scheduler); |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | |
| | | /** |
| | | * Creates a new fail-over load balancing algorithm which will use a default |
| | | * scheduler for monitoring offline connection factories every 10 seconds. |
| | | * Creates a new fail-over load balancing algorithm which will monitor offline |
| | | * connection factories every 10 seconds using the default scheduler. |
| | | * |
| | | * @param factories |
| | | * The ordered collection of connection factories. |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new fail-over load balancing algorithm which will use the |
| | | * provided scheduler for monitoring offline connection factories every 10 |
| | | * seconds. |
| | | * Creates a new fail-over load balancing algorithm which will monitor offline |
| | | * connection factories using the specified frequency using the default |
| | | * scheduler. |
| | | * |
| | | * @param factories |
| | | * The ordered collection of connection factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring offline |
| | | * connection factories to see if they are usable again. |
| | | * The connection factories. |
| | | * @param interval |
| | | * The interval between attempts to poll offline factories. |
| | | * @param unit |
| | | * The time unit for the interval between attempts to poll offline |
| | | * factories. |
| | | */ |
| | | public FailoverLoadBalancingAlgorithm( |
| | | final Collection<ConnectionFactory> factories, |
| | | final ScheduledExecutorService scheduler) |
| | | final Collection<ConnectionFactory> factories, final long interval, |
| | | final TimeUnit unit) |
| | | { |
| | | super(factories, scheduler); |
| | | super(factories, interval, unit); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new fail-over load balancing algorithm which will use the |
| | | * provided scheduler for monitoring offline connection factories. |
| | | * Creates a new fail-over load balancing algorithm which will monitor offline |
| | | * connection factories using the specified frequency and scheduler. |
| | | * |
| | | * @param factories |
| | | * The ordered collection of connection factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring offline |
| | | * connection factories to see if they are usable again. |
| | | * The connection factories. |
| | | * @param interval |
| | | * The interval between attempts to poll offline connection |
| | | * factories. |
| | | * The interval between attempts to poll offline factories. |
| | | * @param unit |
| | | * The time unit for the interval between attempts to poll offline |
| | | * connection factories. |
| | | * factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring dead |
| | | * connection factories to see if they are usable again. |
| | | */ |
| | | public FailoverLoadBalancingAlgorithm( |
| | | final Collection<ConnectionFactory> factories, |
| | | final ScheduledExecutorService scheduler, final long interval, |
| | | final TimeUnit unit) |
| | | final Collection<ConnectionFactory> factories, final long interval, |
| | | final TimeUnit unit, final ScheduledExecutorService scheduler) |
| | | { |
| | | super(factories, scheduler, interval, unit); |
| | | super(factories, interval, unit, scheduler); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | import java.util.concurrent.ScheduledFuture; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import org.opends.sdk.requests.*; |
| | | import org.opends.sdk.responses.*; |
| | | import org.opends.sdk.schema.Schema; |
| | | import org.opends.sdk.requests.Requests; |
| | | import org.opends.sdk.requests.SearchRequest; |
| | | import org.opends.sdk.responses.ExtendedResult; |
| | | import org.opends.sdk.responses.Result; |
| | | import org.opends.sdk.responses.SearchResultEntry; |
| | | import org.opends.sdk.responses.SearchResultReference; |
| | | |
| | | import com.sun.opends.sdk.util.AsynchronousConnectionDecorator; |
| | | import com.sun.opends.sdk.util.FutureResultTransformer; |
| | | import com.sun.opends.sdk.util.StaticUtils; |
| | | import com.sun.opends.sdk.util.Validator; |
| | | |
| | | |
| | | |
| | |
| | | * An asynchronous connection that sends heart beats and supports all |
| | | * operations. |
| | | */ |
| | | private final class AsynchronousConnectionImpl implements |
| | | AsynchronousConnection, ConnectionEventListener, SearchResultHandler |
| | | private final class AsynchronousConnectionImpl extends |
| | | AsynchronousConnectionDecorator implements ConnectionEventListener, |
| | | SearchResultHandler |
| | | { |
| | | private final AsynchronousConnection connection; |
| | | |
| | | private long lastSuccessfulPing; |
| | | |
| | | private FutureResult<Result> lastPingFuture; |
| | |
| | | |
| | | private AsynchronousConnectionImpl(final AsynchronousConnection connection) |
| | | { |
| | | this.connection = connection; |
| | | super(connection); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Void> abandon(final AbandonRequest request) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.abandon(request); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> add(final AddRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.add(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> add(final AddRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection |
| | | .add(request, resultHandler, intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void addConnectionEventListener( |
| | | final ConnectionEventListener listener) throws IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | connection.addConnectionEventListener(listener); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<BindResult> bind(final BindRequest request, |
| | | final ResultHandler<? super BindResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.bind(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<BindResult> bind(final BindRequest request, |
| | | final ResultHandler<? super BindResult> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.bind(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void close() |
| | | { |
| | | synchronized (activeConnections) |
| | | { |
| | | connection.removeConnectionEventListener(this); |
| | | activeConnections.remove(this); |
| | | } |
| | | connection.close(); |
| | | } |
| | | |
| | | |
| | | |
| | | public void close(final UnbindRequest request, final String reason) |
| | | throws NullPointerException |
| | | { |
| | | synchronized (activeConnections) |
| | | { |
| | | connection.removeConnectionEventListener(this); |
| | | activeConnections.remove(this); |
| | | } |
| | | connection.close(request, reason); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<CompareResult> compare(final CompareRequest request, |
| | | final ResultHandler<? super CompareResult> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<CompareResult> compare(final CompareRequest request, |
| | | final ResultHandler<? super CompareResult> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.compare(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void handleConnectionClosed() |
| | | { |
| | | // Ignore - we intercept close through the close method. |
| | | notifyClosed(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void handleConnectionError(final boolean isDisconnectNotification, |
| | | final ErrorResultException error) |
| | | { |
| | | synchronized (activeConnections) |
| | | { |
| | | connection.removeConnectionEventListener(this); |
| | | activeConnections.remove(this); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleUnsolicitedNotification(final ExtendedResult notification) |
| | | { |
| | | // Do nothing |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> delete(final DeleteRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> delete(final DeleteRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.delete(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | final ExtendedRequest<R> request, final ResultHandler<? super R> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public <R extends ExtendedResult> FutureResult<R> extendedRequest( |
| | | final ExtendedRequest<R> request, |
| | | final ResultHandler<? super R> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.extendedRequest(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | notifyClosed(); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Connection getSynchronousConnection() |
| | | { |
| | | return new SynchronousConnection(this); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean handleEntry(SearchResultEntry entry) |
| | | @Override |
| | | public boolean handleEntry(final SearchResultEntry entry) |
| | | { |
| | | // Ignore. |
| | | return true; |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void handleErrorResult(final ErrorResultException error) |
| | | { |
| | | connection.close(Requests.newUnbindRequest(), "Heartbeat retured error: " |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean handleReference(SearchResultReference reference) |
| | | @Override |
| | | public boolean handleReference(final SearchResultReference reference) |
| | | { |
| | | // Ignore. |
| | | return true; |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void handleResult(final Result result) |
| | | { |
| | | lastSuccessfulPing = System.currentTimeMillis(); |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isClosed() |
| | | @Override |
| | | public void handleUnsolicitedNotification(final ExtendedResult notification) |
| | | { |
| | | return connection.isClosed(); |
| | | // Do nothing |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isValid() |
| | | { |
| | | return connection.isValid() |
| | | && (lastSuccessfulPing <= 0 || System.currentTimeMillis() |
| | | - lastSuccessfulPing < unit.toMillis(timeout) * 2); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modify(final ModifyRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modify(final ModifyRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modify(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modifyDN(final ModifyDNRequest request, |
| | | final ResultHandler<? super Result> handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> modifyDN(final ModifyDNRequest request, |
| | | final ResultHandler<? super Result> resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.modifyDN(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | - lastSuccessfulPing < unit.toMillis(interval) * 2); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<SearchResultEntry> readEntry(final DN name, |
| | | final Collection<String> attributeDescriptions, |
| | | final ResultHandler<? super SearchResultEntry> resultHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.readEntry(name, attributeDescriptions, resultHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<RootDSE> readRootDSE( |
| | | final ResultHandler<? super RootDSE> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readRootDSE(handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<Schema> readSchema(final DN name, |
| | | final ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchema(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<Schema> readSchemaForEntry(final DN name, |
| | | final ResultHandler<? super Schema> handler) |
| | | throws UnsupportedOperationException, IllegalStateException |
| | | { |
| | | return connection.readSchemaForEntry(name, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public void removeConnectionEventListener( |
| | | final ConnectionEventListener listener) throws NullPointerException |
| | | { |
| | | connection.removeConnectionEventListener(listener); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> search(final SearchRequest request, |
| | | final SearchResultHandler handler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.search(request, handler); |
| | | } |
| | | |
| | | |
| | | |
| | | public FutureResult<Result> search(final SearchRequest request, |
| | | final SearchResultHandler resultHandler, |
| | | final IntermediateResponseHandler intermediateResponseHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.search(request, resultHandler, |
| | | intermediateResponseHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public FutureResult<SearchResultEntry> searchSingleEntry( |
| | | final SearchRequest request, |
| | | final ResultHandler<? super SearchResultEntry> resultHandler) |
| | | throws UnsupportedOperationException, IllegalStateException, |
| | | NullPointerException |
| | | { |
| | | return connection.searchSingleEntry(request, resultHandler); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | StringBuilder builder = new StringBuilder(); |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("HeartBeatConnection("); |
| | | builder.append(connection); |
| | | builder.append(')'); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | private void notifyClosed() |
| | | { |
| | | synchronized (activeConnections) |
| | | { |
| | | connection.removeConnectionEventListener(this); |
| | | activeConnections.remove(this); |
| | | |
| | | if (activeConnections.isEmpty()) |
| | | { |
| | | // This is the last active connection, so stop the heart beat. |
| | | heartBeatFuture.cancel(false); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | synchronized (activeConnections) |
| | | { |
| | | connection.addConnectionEventListener(heartBeatConnection); |
| | | if (activeConnections.isEmpty()) |
| | | { |
| | | // This is the first active connection, so start the heart beat. |
| | | heartBeatFuture = scheduler.scheduleWithFixedDelay( |
| | | new HeartBeatRunnable(), 0, interval, unit); |
| | | } |
| | | activeConnections.add(heartBeatConnection); |
| | | } |
| | | return heartBeatConnection; |
| | |
| | | |
| | | |
| | | |
| | | private final class HeartBeatThread extends Thread |
| | | private final class HeartBeatRunnable implements Runnable |
| | | { |
| | | private HeartBeatThread() |
| | | private HeartBeatRunnable() |
| | | { |
| | | super("Heart Beat Thread"); |
| | | this.setDaemon(true); |
| | | // Nothing to do. |
| | | } |
| | | |
| | | |
| | |
| | | @Override |
| | | public void run() |
| | | { |
| | | long startTime; |
| | | while (true) |
| | | { |
| | | startTime = System.currentTimeMillis(); |
| | | synchronized (activeConnections) |
| | | { |
| | | for (final AsynchronousConnectionImpl connection : activeConnections) |
| | |
| | | } |
| | | } |
| | | } |
| | | try |
| | | { |
| | | final long sleepTime = unit.toMillis(timeout) |
| | | - (System.currentTimeMillis() - startTime); |
| | | if (sleepTime > 0) |
| | | { |
| | | sleep(sleepTime); |
| | | } |
| | | } |
| | | catch (final InterruptedException e) |
| | | { |
| | | // Ignore |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | private final SearchRequest heartBeat; |
| | | |
| | | private final long timeout; |
| | | private final long interval; |
| | | |
| | | // FIXME: use a single global scheduler? |
| | | private final ScheduledExecutorService scheduler; |
| | | |
| | | private final TimeUnit unit; |
| | | |
| | | private final List<AsynchronousConnectionImpl> activeConnections; |
| | | |
| | | private final ConnectionFactory parentFactory; |
| | | private final ConnectionFactory factory; |
| | | |
| | | private static final SearchRequest DEFAULT_SEARCH = Requests |
| | | .newSearchRequest("", SearchScope.BASE_OBJECT, "(objectClass=*)", "1.1"); |
| | | |
| | | private ScheduledFuture<?> heartBeatFuture; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new heart-beat connection factory which will create connections |
| | | * using the provided connection factory and periodically ping any created |
| | | * connections in order to detect that they are still alive. |
| | | * connections in order to detect that they are still alive every 10 seconds |
| | | * using the default scheduler. |
| | | * |
| | | * @param connectionFactory |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param timeout |
| | | * The time to wait between keepalive pings. |
| | | * @param unit |
| | | * The time unit of the timeout argument. |
| | | */ |
| | | HeartBeatConnectionFactory(final ConnectionFactory connectionFactory, |
| | | final long timeout, final TimeUnit unit) |
| | | HeartBeatConnectionFactory(final ConnectionFactory factory) |
| | | { |
| | | this(connectionFactory, timeout, unit, DEFAULT_SEARCH); |
| | | this(factory, 10, TimeUnit.SECONDS, DEFAULT_SEARCH, StaticUtils |
| | | .getDefaultScheduler()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new heart-beat connection factory which will create connections |
| | | * using the provided connection factory and periodically ping any created |
| | | * connections in order to detect that they are still alive using the |
| | | * specified frequency and the default scheduler. |
| | | * |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param interval |
| | | * The interval between keepalive pings. |
| | | * @param unit |
| | | * The time unit for the interval between keepalive pings. |
| | | */ |
| | | HeartBeatConnectionFactory(final ConnectionFactory factory, |
| | | final long interval, final TimeUnit unit) |
| | | { |
| | | this(factory, interval, unit, DEFAULT_SEARCH, StaticUtils |
| | | .getDefaultScheduler()); |
| | | } |
| | | |
| | | |
| | |
| | | * connections using the specified search request in order to detect that they |
| | | * are still alive. |
| | | * |
| | | * @param connectionFactory |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param timeout |
| | | * The time to wait between keepalive pings. |
| | | * @param interval |
| | | * The interval between keepalive pings. |
| | | * @param unit |
| | | * The time unit of the timeout argument. |
| | | * The time unit for the interval between keepalive pings. |
| | | * @param heartBeat |
| | | * The search request to use when pinging connections. |
| | | * The search request to use for keepalive pings. |
| | | */ |
| | | HeartBeatConnectionFactory(final ConnectionFactory connectionFactory, |
| | | final long timeout, final TimeUnit unit, final SearchRequest heartBeat) |
| | | HeartBeatConnectionFactory(final ConnectionFactory factory, |
| | | final long interval, final TimeUnit unit, final SearchRequest heartBeat) |
| | | { |
| | | this(factory, interval, unit, heartBeat, StaticUtils.getDefaultScheduler()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new heart-beat connection factory which will create connections |
| | | * using the provided connection factory and periodically ping any created |
| | | * connections using the specified search request in order to detect that they |
| | | * are still alive. |
| | | * |
| | | * @param factory |
| | | * The connection factory to use for creating connections. |
| | | * @param interval |
| | | * The interval between keepalive pings. |
| | | * @param unit |
| | | * The time unit for the interval between keepalive pings. |
| | | * @param heartBeat |
| | | * The search request to use for keepalive pings. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically sending keepalive |
| | | * pings. |
| | | */ |
| | | HeartBeatConnectionFactory(final ConnectionFactory factory, |
| | | final long interval, final TimeUnit unit, final SearchRequest heartBeat, |
| | | final ScheduledExecutorService scheduler) |
| | | { |
| | | Validator.ensureNotNull(factory, heartBeat, unit, scheduler); |
| | | Validator.ensureTrue(interval >= 0, "negative timeout"); |
| | | |
| | | this.heartBeat = heartBeat; |
| | | this.timeout = timeout; |
| | | this.interval = interval; |
| | | this.unit = unit; |
| | | this.activeConnections = new LinkedList<AsynchronousConnectionImpl>(); |
| | | this.parentFactory = connectionFactory; |
| | | |
| | | new HeartBeatThread().start(); |
| | | this.factory = factory; |
| | | this.scheduler = scheduler; |
| | | } |
| | | |
| | | |
| | |
| | | final ResultHandler<? super AsynchronousConnection> handler) |
| | | { |
| | | final FutureResultImpl future = new FutureResultImpl(handler); |
| | | future.setFutureResult(parentFactory.getAsynchronousConnection(future)); |
| | | future.setFutureResult(factory.getAsynchronousConnection(future)); |
| | | return future; |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | final StringBuilder builder = new StringBuilder(); |
| | | builder.append("HeartBeatConnectionFactory("); |
| | | builder.append(String.valueOf(parentFactory)); |
| | | builder.append(String.valueOf(factory)); |
| | | builder.append(')'); |
| | | return builder.toString(); |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new round robin load balancing algorithm which will use a default |
| | | * scheduler for monitoring offline connection factories every 10 seconds. |
| | | * Creates a new round robin load balancing algorithm which will monitor |
| | | * offline connection factories every 10 seconds using the default scheduler. |
| | | * |
| | | * @param factories |
| | | * The unordered collection of connection factories. |
| | | * The ordered collection of connection factories. |
| | | */ |
| | | public RoundRobinLoadBalancingAlgorithm( |
| | | final Collection<ConnectionFactory> factories) |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new round robin load balancing algorithm which will use the |
| | | * provided scheduler for monitoring offline connection factories every 10 |
| | | * seconds. |
| | | * Creates a new round robin load balancing algorithm which will monitor |
| | | * offline connection factories using the specified frequency using the |
| | | * default scheduler. |
| | | * |
| | | * @param factories |
| | | * The unordered collection of connection factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring offline |
| | | * connection factories to see if they are usable again. |
| | | * The connection factories. |
| | | * @param interval |
| | | * The interval between attempts to poll offline factories. |
| | | * @param unit |
| | | * The time unit for the interval between attempts to poll offline |
| | | * factories. |
| | | */ |
| | | public RoundRobinLoadBalancingAlgorithm( |
| | | final Collection<ConnectionFactory> factories, |
| | | final ScheduledExecutorService scheduler) |
| | | final Collection<ConnectionFactory> factories, final long interval, |
| | | final TimeUnit unit) |
| | | { |
| | | super(factories, scheduler); |
| | | super(factories, interval, unit); |
| | | this.maxIndex = factories.size(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new round robin load balancing algorithm which will use the |
| | | * provided scheduler for monitoring offline connection factories. |
| | | * Creates a new round robin load balancing algorithm which will monitor |
| | | * offline connection factories using the specified frequency and scheduler. |
| | | * |
| | | * @param factories |
| | | * The unordered collection of connection factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring offline |
| | | * connection factories to see if they are usable again. |
| | | * The connection factories. |
| | | * @param interval |
| | | * The interval between attempts to poll offline connection |
| | | * factories. |
| | | * The interval between attempts to poll offline factories. |
| | | * @param unit |
| | | * The time unit for the interval between attempts to poll offline |
| | | * connection factories. |
| | | * factories. |
| | | * @param scheduler |
| | | * The scheduler which should for periodically monitoring dead |
| | | * connection factories to see if they are usable again. |
| | | */ |
| | | public RoundRobinLoadBalancingAlgorithm( |
| | | final Collection<ConnectionFactory> factories, |
| | | final ScheduledExecutorService scheduler, final long interval, |
| | | final TimeUnit unit) |
| | | final Collection<ConnectionFactory> factories, final long interval, |
| | | final TimeUnit unit, final ScheduledExecutorService scheduler) |
| | | { |
| | | super(factories, scheduler, interval, unit); |
| | | super(factories, interval, unit, scheduler); |
| | | this.maxIndex = factories.size(); |
| | | } |
| | | |
| | |
| | | import java.util.Arrays; |
| | | import java.util.concurrent.CountDownLatch; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | |
| | | import org.opends.sdk.requests.*; |
| | | import org.opends.sdk.responses.*; |
| | |
| | | public class LDAPListenerTestCase extends SdkTestCase |
| | | { |
| | | |
| | | private static class MockConnectionEventListener implements |
| | | ConnectionEventListener |
| | | { |
| | | final CountDownLatch closeLatch = new CountDownLatch(1); |
| | | String errorMessage = null; |
| | | |
| | | |
| | | |
| | | public void handleUnsolicitedNotification(ExtendedResult notification) |
| | | { |
| | | errorMessage = "Unexpected call to handleUnsolicitedNotification"; |
| | | closeLatch.countDown(); |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleConnectionError(boolean isDisconnectNotification, |
| | | ErrorResultException error) |
| | | { |
| | | errorMessage = "Unexpected call to handleConnectionError"; |
| | | closeLatch.countDown(); |
| | | } |
| | | |
| | | |
| | | |
| | | public void handleConnectionClosed() |
| | | { |
| | | errorMessage = "Unexpected call to handleConnectionClosed"; |
| | | closeLatch.countDown(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private static class MockServerConnection implements |
| | | ServerConnection<Integer> |
| | | { |
| | |
| | | Assert.assertTrue(connection.isClosed()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests connection event listener. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testConnectionEventListenerClose() throws Exception |
| | | { |
| | | final MockServerConnection onlineServerConnection = new MockServerConnection(); |
| | | final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory( |
| | | onlineServerConnection); |
| | | final LDAPListener onlineServerListener = new LDAPListener("localhost", |
| | | TestCaseUtils.findFreePort(), onlineServerConnectionFactory); |
| | | |
| | | final Connection connection; |
| | | try |
| | | { |
| | | // Connect and bind. |
| | | connection = new LDAPConnectionFactory( |
| | | onlineServerListener.getSocketAddress()).getConnection(); |
| | | |
| | | MockConnectionEventListener listener = new MockConnectionEventListener() |
| | | { |
| | | |
| | | public void handleConnectionClosed() |
| | | { |
| | | closeLatch.countDown(); |
| | | } |
| | | }; |
| | | |
| | | connection.addConnectionEventListener(listener); |
| | | Assert.assertEquals(listener.closeLatch.getCount(), 1); |
| | | connection.close(); |
| | | listener.closeLatch.await(); |
| | | Assert.assertNull(listener.errorMessage); |
| | | } |
| | | finally |
| | | { |
| | | onlineServerListener.close(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests connection event listener. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testConnectionEventListenerUnbind() throws Exception |
| | | { |
| | | final MockServerConnection onlineServerConnection = new MockServerConnection(); |
| | | final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory( |
| | | onlineServerConnection); |
| | | final LDAPListener onlineServerListener = new LDAPListener("localhost", |
| | | TestCaseUtils.findFreePort(), onlineServerConnectionFactory); |
| | | |
| | | final Connection connection; |
| | | try |
| | | { |
| | | // Connect and bind. |
| | | connection = new LDAPConnectionFactory( |
| | | onlineServerListener.getSocketAddress()).getConnection(); |
| | | |
| | | MockConnectionEventListener listener = new MockConnectionEventListener() |
| | | { |
| | | |
| | | public void handleConnectionClosed() |
| | | { |
| | | closeLatch.countDown(); |
| | | } |
| | | }; |
| | | |
| | | connection.addConnectionEventListener(listener); |
| | | Assert.assertEquals(listener.closeLatch.getCount(), 1); |
| | | connection.close(Requests.newUnbindRequest(), "called from unit test"); |
| | | listener.closeLatch.await(); |
| | | Assert.assertNull(listener.errorMessage); |
| | | } |
| | | finally |
| | | { |
| | | onlineServerListener.close(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests connection event listener. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testConnectionEventListenerDisconnect() throws Exception |
| | | { |
| | | final MockServerConnection onlineServerConnection = new MockServerConnection(); |
| | | final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory( |
| | | onlineServerConnection); |
| | | final LDAPListener onlineServerListener = new LDAPListener("localhost", |
| | | TestCaseUtils.findFreePort(), onlineServerConnectionFactory); |
| | | |
| | | final Connection connection; |
| | | try |
| | | { |
| | | // Connect and bind. |
| | | connection = new LDAPConnectionFactory( |
| | | onlineServerListener.getSocketAddress()).getConnection(); |
| | | |
| | | MockConnectionEventListener listener = new MockConnectionEventListener() |
| | | { |
| | | |
| | | public void handleConnectionError(boolean isDisconnectNotification, |
| | | ErrorResultException error) |
| | | { |
| | | if (isDisconnectNotification) |
| | | { |
| | | errorMessage = "Unexpected disconnect notification"; |
| | | } |
| | | closeLatch.countDown(); |
| | | } |
| | | }; |
| | | |
| | | connection.addConnectionEventListener(listener); |
| | | Assert.assertEquals(listener.closeLatch.getCount(), 1); |
| | | onlineServerConnection.context.disconnect(); |
| | | listener.closeLatch.await(); |
| | | Assert.assertNull(listener.errorMessage); |
| | | connection.close(); |
| | | } |
| | | finally |
| | | { |
| | | onlineServerListener.close(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests connection event listener. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testConnectionEventListenerDisconnectNotification() |
| | | throws Exception |
| | | { |
| | | final MockServerConnection onlineServerConnection = new MockServerConnection(); |
| | | final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory( |
| | | onlineServerConnection); |
| | | final LDAPListener onlineServerListener = new LDAPListener("localhost", |
| | | TestCaseUtils.findFreePort(), onlineServerConnectionFactory); |
| | | |
| | | final Connection connection; |
| | | try |
| | | { |
| | | // Connect and bind. |
| | | connection = new LDAPConnectionFactory( |
| | | onlineServerListener.getSocketAddress()).getConnection(); |
| | | |
| | | MockConnectionEventListener listener = new MockConnectionEventListener() |
| | | { |
| | | |
| | | public void handleConnectionError(boolean isDisconnectNotification, |
| | | ErrorResultException error) |
| | | { |
| | | if (!isDisconnectNotification |
| | | || !error.getResult().getResultCode().equals(ResultCode.BUSY) |
| | | || !error.getResult().getDiagnosticMessage().equals("test")) |
| | | { |
| | | errorMessage = "Missing disconnect notification: " + error; |
| | | } |
| | | closeLatch.countDown(); |
| | | } |
| | | }; |
| | | |
| | | connection.addConnectionEventListener(listener); |
| | | Assert.assertEquals(listener.closeLatch.getCount(), 1); |
| | | onlineServerConnection.context.disconnect(ResultCode.BUSY, "test"); |
| | | listener.closeLatch.await(); |
| | | Assert.assertNull(listener.errorMessage); |
| | | connection.close(); |
| | | } |
| | | finally |
| | | { |
| | | onlineServerListener.close(); |
| | | } |
| | | } |
| | | } |