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