001/*
002 * Copyright 2009-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2009-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) 2009-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.unboundidds.extensions;
037
038
039
040import java.io.Serializable;
041
042import com.unboundid.asn1.ASN1Element;
043import com.unboundid.asn1.ASN1Integer;
044import com.unboundid.asn1.ASN1OctetString;
045import com.unboundid.asn1.ASN1Sequence;
046import com.unboundid.ldap.sdk.LDAPException;
047import com.unboundid.ldap.sdk.ResultCode;
048import com.unboundid.util.Debug;
049import com.unboundid.util.NotMutable;
050import com.unboundid.util.NotNull;
051import com.unboundid.util.StaticUtils;
052import com.unboundid.util.ThreadSafety;
053import com.unboundid.util.ThreadSafetyLevel;
054import com.unboundid.util.Validator;
055
056import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
057
058
059
060/**
061 * This class provides a data structure for holding information about the
062 * configuration of backend sets as used by the stream proxy values extended
063 * request.
064 * <BR>
065 * <BLOCKQUOTE>
066 *   <B>NOTE:</B>  This class, and other classes within the
067 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
068 *   supported for use against Ping Identity, UnboundID, and
069 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
070 *   for proprietary functionality or for external specifications that are not
071 *   considered stable or mature enough to be guaranteed to work in an
072 *   interoperable way with other types of LDAP servers.
073 * </BLOCKQUOTE>
074 */
075@NotMutable()
076@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
077public final class StreamProxyValuesBackendSet
078       implements Serializable
079{
080  /**
081   * The serial version UID for this serializable class.
082   */
083  private static final long serialVersionUID = -5437145469462592611L;
084
085
086
087  // The backend set ID for this backend set.
088  @NotNull private final ASN1OctetString backendSetID;
089
090  // The ports of the directory servers in this backend set.
091  @NotNull private final int[] ports;
092
093  // The addresses of the directory servers in this backend set.
094  @NotNull private final String[] hosts;
095
096
097
098  /**
099   * Creates a new backend set with the provided information.
100   *
101   * @param  backendSetID  The backend set ID for this backend set.  It must not
102   *                       be {@code null}.
103   * @param  hosts         The addresses of the servers for this backend set.
104   *                       It must not be {@code null} or empty, and it must
105   *                       have the same number of elements as the {@code ports}
106   *                       array.
107   * @param  ports         The ports of the servers for this backend set.  It
108   *                       must not be {@code null} or empty, and it must have
109   *                       the same number of elements as the {@code hosts}
110   *                       array.
111   */
112  public StreamProxyValuesBackendSet(
113              @NotNull final ASN1OctetString backendSetID,
114              @NotNull final String[] hosts,
115              @NotNull final int[] ports)
116  {
117    Validator.ensureNotNull(backendSetID, hosts, ports);
118    Validator.ensureTrue(hosts.length > 0);
119    Validator.ensureTrue(hosts.length == ports.length);
120
121    this.backendSetID = backendSetID;
122    this.hosts        = hosts;
123    this.ports        = ports;
124  }
125
126
127
128  /**
129   * Retrieves the backend set ID for this backend set.
130   *
131   * @return  The backend set ID for this backend set.
132   */
133  @NotNull()
134  public ASN1OctetString getBackendSetID()
135  {
136    return backendSetID;
137  }
138
139
140
141  /**
142   * Retrieves the addresses of the servers for this backend set.
143   *
144   * @return  The addresses of the servers for this backend set.
145   */
146  @NotNull()
147  public String[] getHosts()
148  {
149    return hosts;
150  }
151
152
153
154  /**
155   * Retrieves the ports of the servers for this backend set.
156   *
157   * @return  The ports of the servers for this backend set.
158   */
159  @NotNull()
160  public int[] getPorts()
161  {
162    return ports;
163  }
164
165
166
167  /**
168   * Encodes this backend set object in a form suitable for inclusion in the
169   * value of the stream proxy values extended request.
170   *
171   * @return  The encoded representation of this backend set.
172   */
173  @NotNull()
174  public ASN1Element encode()
175  {
176    final ASN1Element[] hostPortElements = new ASN1Element[hosts.length];
177    for (int i=0; i < hosts.length; i++)
178    {
179      hostPortElements[i] = new ASN1Sequence(
180           new ASN1OctetString(hosts[i]),
181           new ASN1Integer(ports[i]));
182    }
183
184    return new ASN1Sequence(
185         backendSetID,
186         new ASN1Sequence(hostPortElements));
187  }
188
189
190
191  /**
192   * Decodes the provided ASN.1 element as a backend set.
193   *
194   * @param  element  The element to be decoded as a backend set.
195   *
196   * @return  The decoded backend set.
197   *
198   * @throws  LDAPException  If the provided ASN.1 element cannot be decoded as
199   *                         a backend set.
200   */
201  @NotNull()
202  public static StreamProxyValuesBackendSet decode(
203              @NotNull final ASN1Element element)
204         throws LDAPException
205  {
206    try
207    {
208      final ASN1Element[] elements =
209           ASN1Sequence.decodeAsSequence(element).elements();
210      final ASN1OctetString backendSetID =
211           ASN1OctetString.decodeAsOctetString(elements[0]);
212
213      final ASN1Element[] hostPortElements =
214           ASN1Sequence.decodeAsSequence(elements[1]).elements();
215      final String[] hosts = new String[hostPortElements.length];
216      final int[]    ports = new int[hostPortElements.length];
217      for (int i=0; i < hostPortElements.length; i++)
218      {
219        final ASN1Element[] hpElements =
220             ASN1Sequence.decodeAsSequence(hostPortElements[i]).elements();
221        hosts[i] =
222             ASN1OctetString.decodeAsOctetString(hpElements[0]).stringValue();
223        ports[i] = ASN1Integer.decodeAsInteger(hpElements[1]).intValue();
224      }
225
226      return new StreamProxyValuesBackendSet(backendSetID, hosts, ports);
227    }
228    catch (final Exception e)
229    {
230      Debug.debugException(e);
231      throw new LDAPException(ResultCode.DECODING_ERROR,
232           ERR_STREAM_PROXY_VALUES_BACKEND_SET_CANNOT_DECODE.get(
233                StaticUtils.getExceptionMessage(e)), e);
234    }
235  }
236
237
238
239  /**
240   * Retrieves a string representation of this stream proxy values backend set.
241   *
242   * @return  A string representation of this stream proxy values backend set.
243   */
244  @Override()
245  @NotNull()
246  public String toString()
247  {
248    final StringBuilder buffer = new StringBuilder();
249    toString(buffer);
250    return buffer.toString();
251  }
252
253
254
255  /**
256   * Appends a string representation of this stream proxy values backend set to
257   * the provided buffer.
258   *
259   * @param  buffer  The buffer to which the stream representation should be
260   *                 appended.
261   */
262  public void toString(@NotNull final StringBuilder buffer)
263  {
264    buffer.append("StreamProxyValuesBackendSet(id=");
265    backendSetID.toString(buffer);
266    buffer.append(", servers={");
267
268    for (int i=0; i < hosts.length; i++)
269    {
270      if (i > 0)
271      {
272        buffer.append(", ");
273      }
274      buffer.append(hosts[i]);
275      buffer.append(':');
276      buffer.append(ports[i]);
277    }
278    buffer.append("})");
279  }
280}