001/*
002 * Copyright 2008-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2019 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk;
022
023
024
025import javax.net.SocketFactory;
026
027import com.unboundid.util.NotMutable;
028import com.unboundid.util.ThreadSafety;
029import com.unboundid.util.ThreadSafetyLevel;
030import com.unboundid.util.Validator;
031
032
033
034/**
035 * This class provides a server set implementation that only provides the
036 * ability to connect to a single server.  It may be used in cases where a
037 * {@link ServerSet} is required but only a single server is needed.
038 */
039@NotMutable()
040@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
041public final class SingleServerSet
042       extends ServerSet
043{
044  // The bind request to use to authenticate connections created by this
045  // server set.
046  private final BindRequest bindRequest;
047
048  // The port number of the target server.
049  private final int port;
050
051  // The set of connection options to use.
052  private final LDAPConnectionOptions connectionOptions;
053
054  // The post-connect processor to invoke against connections created by this
055  // server set.
056  private final PostConnectProcessor postConnectProcessor;
057
058  // The socket factory to use to establish connections.
059  private final SocketFactory socketFactory;
060
061  // The address of the target server.
062  private final String address;
063
064
065
066  /**
067   * Creates a new single server set with the specified address and port.  It
068   * will use the default socket factory provided by the JVM to create the
069   * underlying socket.
070   *
071   * @param  address  The address of the directory server to which the
072   *                  connections should be established.  It must not be
073   *                  {@code null}.
074   * @param  port     The port of the directory server to which the connections
075   *                  should be established.  It must be between 1 and 65535,
076   *                  inclusive.
077   */
078  public SingleServerSet(final String address, final int port)
079  {
080    this(address, port, null, null);
081  }
082
083
084
085  /**
086   * Creates a new single server set with the specified address and port.  It
087   * will use the default socket factory provided by the JVM to create the
088   * underlying socket.
089   *
090   * @param  address            The address of the directory server to which the
091   *                            connections should be established.  It must not
092   *                            be {@code null}.
093   * @param  port               The port of the directory server to which the
094   *                            connections should be established.  It must be
095   *                            between 1 and 65535, inclusive.
096   * @param  connectionOptions  The set of connection options to use for the
097   *                            underlying connections.
098   */
099  public SingleServerSet(final String address, final int port,
100                         final LDAPConnectionOptions connectionOptions)
101  {
102    this(address, port, null, connectionOptions);
103  }
104
105
106
107  /**
108   * Creates a new single server set with the specified address and port, and
109   * using the provided socket factory.
110   *
111   * @param  address        The address of the directory server to which the
112   *                        connections should be established.  It must not be
113   *                        {@code null}.
114   * @param  port           The port of the directory server to which the
115   *                        connections should be established.  It must be
116   *                        between 1 and 65535, inclusive.
117   * @param  socketFactory  The socket factory to use to create the underlying
118   *                        connections.
119   */
120  public SingleServerSet(final String address, final int port,
121                         final SocketFactory socketFactory)
122  {
123    this(address, port, socketFactory, null);
124  }
125
126
127
128  /**
129   * Creates a new single server set with the specified address and port, and
130   * using the provided socket factory.
131   *
132   * @param  address            The address of the directory server to which the
133   *                            connections should be established.  It must not
134   *                            be {@code null}.
135   * @param  port               The port of the directory server to which the
136   *                            connections should be established.  It must be
137   *                            between 1 and 65535, inclusive.
138   * @param  socketFactory      The socket factory to use to create the
139   *                            underlying connections.
140   * @param  connectionOptions  The set of connection options to use for the
141   *                            underlying connections.
142   */
143  public SingleServerSet(final String address, final int port,
144                         final SocketFactory socketFactory,
145                         final LDAPConnectionOptions connectionOptions)
146  {
147    this(address, port, socketFactory, connectionOptions, null, null);
148  }
149
150
151
152  /**
153   * Creates a new single server set with the specified address and port, and
154   * using the provided socket factory.
155   *
156   * @param  address               The address of the directory server to which
157   *                               the connections should be established.  It
158   *                               must not be {@code null}.
159   * @param  port                  The port of the directory server to which the
160   *                               connections should be established.  It must
161   *                               be between 1 and 65535, inclusive.
162   * @param  socketFactory         The socket factory to use to create the
163   *                               underlying connections.
164   * @param  connectionOptions     The set of connection options to use for the
165   *                               underlying connections.
166   * @param  bindRequest           The bind request that should be used to
167   *                               authenticate newly-established connections.
168   *                               It may be {@code null} if this server set
169   *                               should not perform any authentication.
170   * @param  postConnectProcessor  The post-connect processor that should be
171   *                               invoked on newly-established connections.  It
172   *                               may be {@code null} if this server set should
173   *                               not perform any post-connect processing.
174   */
175  public SingleServerSet(final String address, final int port,
176                         final SocketFactory socketFactory,
177                         final LDAPConnectionOptions connectionOptions,
178                         final BindRequest bindRequest,
179                         final PostConnectProcessor postConnectProcessor)
180  {
181    Validator.ensureNotNull(address);
182    Validator.ensureTrue((port > 0) && (port < 65_536),
183         "SingleServerSet.port must be between 1 and 65535.");
184
185    this.address = address;
186    this.port = port;
187    this.bindRequest = bindRequest;
188    this.postConnectProcessor = postConnectProcessor;
189
190    if (socketFactory == null)
191    {
192      this.socketFactory = SocketFactory.getDefault();
193    }
194    else
195    {
196      this.socketFactory = socketFactory;
197    }
198
199    if (connectionOptions == null)
200    {
201      this.connectionOptions = new LDAPConnectionOptions();
202    }
203    else
204    {
205      this.connectionOptions = connectionOptions;
206    }
207  }
208
209
210
211  /**
212   * Retrieves the address of the directory server to which the connections
213   * should be established.
214   *
215   * @return  The address of the directory server to which the connections
216   *          should be established.
217   */
218  public String getAddress()
219  {
220    return address;
221  }
222
223
224
225  /**
226   * Retrieves the port of the directory server to which the connections should
227   * be established.
228   *
229   * @return  The port of the directory server to which the connections should
230   *          be established.
231   */
232  public int getPort()
233  {
234    return port;
235  }
236
237
238
239  /**
240   * Retrieves the socket factory that will be used to establish connections.
241   *
242   * @return  The socket factory that will be used to establish connections.
243   */
244  public SocketFactory getSocketFactory()
245  {
246    return socketFactory;
247  }
248
249
250
251  /**
252   * Retrieves the set of connection options that will be used by the underlying
253   * connections.
254   *
255   * @return  The set of connection options that will be used by the underlying
256   *          connections.
257   */
258  public LDAPConnectionOptions getConnectionOptions()
259  {
260    return connectionOptions;
261  }
262
263
264
265  /**
266   * {@inheritDoc}
267   */
268  @Override()
269  public boolean includesAuthentication()
270  {
271    return (bindRequest != null);
272  }
273
274
275
276  /**
277   * {@inheritDoc}
278   */
279  @Override()
280  public boolean includesPostConnectProcessing()
281  {
282    return (postConnectProcessor != null);
283  }
284
285
286
287  /**
288   * {@inheritDoc}
289   */
290  @Override()
291  public LDAPConnection getConnection()
292         throws LDAPException
293  {
294    return getConnection(null);
295  }
296
297
298
299  /**
300   * {@inheritDoc}
301   */
302  @Override()
303  public LDAPConnection getConnection(
304                             final LDAPConnectionPoolHealthCheck healthCheck)
305         throws LDAPException
306  {
307    final LDAPConnection connection =
308         new LDAPConnection(socketFactory, connectionOptions, address, port);
309    doBindPostConnectAndHealthCheckProcessing(connection, bindRequest,
310         postConnectProcessor, healthCheck);
311    associateConnectionWithThisServerSet(connection);
312    return connection;
313  }
314
315
316
317  /**
318   * {@inheritDoc}
319   */
320  @Override()
321  public void toString(final StringBuilder buffer)
322  {
323    buffer.append("SingleServerSet(server=");
324    buffer.append(address);
325    buffer.append(':');
326    buffer.append(port);
327    buffer.append(", includesAuthentication=");
328    buffer.append(bindRequest != null);
329    buffer.append(", includesPostConnectProcessing=");
330    buffer.append(postConnectProcessor != null);
331    buffer.append(')');
332  }
333}