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