001/*
002 * Copyright 2013-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.controls;
022
023
024
025import java.io.Serializable;
026import java.util.ArrayList;
027
028import com.unboundid.asn1.ASN1Element;
029import com.unboundid.asn1.ASN1Enumerated;
030import com.unboundid.asn1.ASN1Integer;
031import com.unboundid.asn1.ASN1Sequence;
032import com.unboundid.ldap.sdk.LDAPException;
033import com.unboundid.ldap.sdk.ResultCode;
034import com.unboundid.util.Debug;
035import com.unboundid.util.NotMutable;
036import com.unboundid.util.StaticUtils;
037import com.unboundid.util.ThreadSafety;
038import com.unboundid.util.ThreadSafetyLevel;
039
040import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;
041
042
043
044/**
045 * This class defines a data structure that provides information about the
046 * result of assured replication processing, either on a replication server (if
047 * that is all that is needed to satisfy the desired level of assurance) or
048 * on a directory server (if required by the desired level of assurance).
049 * <BR>
050 * <BLOCKQUOTE>
051 *   <B>NOTE:</B>  This class, and other classes within the
052 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
053 *   supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661
054 *   server products.  These classes provide support for proprietary
055 *   functionality or for external specifications that are not considered stable
056 *   or mature enough to be guaranteed to work in an interoperable way with
057 *   other types of LDAP servers.
058 * </BLOCKQUOTE>
059 */
060@NotMutable()
061@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
062public final class AssuredReplicationServerResult
063       implements Serializable
064{
065  /**
066   * The BER type for the result code element.
067   */
068  private static final byte TYPE_RESULT_CODE = (byte) 0x80;
069
070
071  /**
072   * The BER type for the server ID element.
073   */
074  private static final byte TYPE_SERVER_ID = (byte) 0x81;
075
076
077  /**
078   * The BER type for the replica ID element.
079   */
080  private static final byte TYPE_REPLICA_ID = (byte) 0x82;
081
082
083
084  /**
085   * The serial version UID for this serializable class.
086   */
087  private static final long serialVersionUID = 3015162215769386343L;
088
089
090
091  // The result code for this server result.
092  private final AssuredReplicationServerResultCode resultCode;
093
094  // The replica ID of the associated directory server.
095  private final Short replicaID;
096
097  // The server ID of the associated replication server.
098  private final Short replicationServerID;
099
100
101
102  /**
103   * Creates a new assured replication server result with the provided
104   * information.
105   *
106   * @param  resultCode           The result code that indicates the state of
107   *                              assurance processing for the associated
108   *                              replication server and/or directory server.
109   *                              It must not be {@code null}.
110   * @param  replicationServerID  The server ID of the replication server from
111   *                              which this server result was obtained.  It may
112   *                              be {@code null} if no replication server ID is
113   *                              available for this result.
114   * @param  replicaID            The replica ID of the directory server with
115   *                              which this result is associated.  It may be
116   *                              {@code null} if no replica ID is available
117   *                              for this result.
118   */
119  public AssuredReplicationServerResult(
120       final AssuredReplicationServerResultCode resultCode,
121       final Short replicationServerID,
122       final Short replicaID)
123  {
124    this.resultCode = resultCode;
125    this.replicationServerID = replicationServerID;
126    this.replicaID = replicaID;
127  }
128
129
130
131  /**
132   * Retrieves the result code that indicates the state of assurance processing
133   * for this server result.
134   *
135   * @return  The result code for this server result.
136   */
137  public AssuredReplicationServerResultCode getResultCode()
138  {
139    return resultCode;
140  }
141
142
143
144  /**
145   * Retrieves the server ID for the replication server from which this server
146   * result was obtained, if available.
147   *
148   * @return  The server ID for the replication server from which this server
149   *          result was obtained, or {@code null} if no replication server ID
150   *          is available.
151   */
152  public Short getReplicationServerID()
153  {
154    return replicationServerID;
155  }
156
157
158
159  /**
160   * Retrieves the replica ID for the directory server with which this server
161   * result is associated, if applicable.
162   *
163   * @return  The replica ID for the directory server with which this server
164   *          result is associated, or {@code null} if there is no associated
165   *          directory server.
166   */
167  public Short getReplicaID()
168  {
169    return replicaID;
170  }
171
172
173
174  /**
175   * Encodes this assured replication server result to an ASN.1 element suitable
176   * for use in a {@link AssuredReplicationResponseControl}.
177   *
178   * @return  The encoded representation of this assured replication server
179   *          result.
180   */
181  ASN1Element encode()
182  {
183    final ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(3);
184
185    elements.add(new ASN1Enumerated(TYPE_RESULT_CODE, resultCode.intValue()));
186
187    if (replicationServerID != null)
188    {
189      elements.add(new ASN1Integer(TYPE_SERVER_ID, replicationServerID));
190    }
191
192    if (replicaID != null)
193    {
194      elements.add(new ASN1Integer(TYPE_REPLICA_ID, replicaID));
195    }
196
197    return new ASN1Sequence(elements);
198  }
199
200
201
202  /**
203   * Decodes the provided ASN.1 element as an assured replication server
204   * result.
205   *
206   * @param  element  The ASN.1 element to be decoded.  It must not be
207   *                  {@code null}.
208   *
209   * @return  The decoded assured replication server result.
210   *
211   * @throws  LDAPException  If a problem is encountered while attempting to
212   *                         decode the provided ASN.1 element as an assured
213   *                         replication server result.
214   */
215  static AssuredReplicationServerResult decode(final ASN1Element element)
216         throws LDAPException
217  {
218    AssuredReplicationServerResultCode resultCode = null;
219    Short serverID  = null;
220    Short replicaID = null;
221
222    try
223    {
224      for (final ASN1Element e :
225           ASN1Sequence.decodeAsSequence(element).elements())
226      {
227        switch (e.getType())
228        {
229          case TYPE_RESULT_CODE:
230            final int rcValue = ASN1Enumerated.decodeAsEnumerated(e).intValue();
231            resultCode = AssuredReplicationServerResultCode.valueOf(rcValue);
232            if (resultCode == null)
233            {
234              throw new LDAPException(ResultCode.DECODING_ERROR,
235                   ERR_ASSURED_REPLICATION_SERVER_RESULT_INVALID_RESULT_CODE.
236                        get(rcValue));
237            }
238            break;
239
240          case TYPE_SERVER_ID:
241            serverID = (short) ASN1Integer.decodeAsInteger(e).intValue();
242            break;
243
244          case TYPE_REPLICA_ID:
245            replicaID = (short) ASN1Integer.decodeAsInteger(e).intValue();
246            break;
247
248          default:
249            throw new LDAPException(ResultCode.DECODING_ERROR,
250                 ERR_ASSURED_REPLICATION_SERVER_RESULT_UNEXPECTED_ELEMENT_TYPE.
251                      get(StaticUtils.toHex(e.getType())));
252        }
253      }
254    }
255    catch (final LDAPException le)
256    {
257      Debug.debugException(le);
258      throw le;
259    }
260    catch (final Exception e)
261    {
262      Debug.debugException(e);
263      throw new LDAPException(ResultCode.DECODING_ERROR,
264           ERR_ASSURED_REPLICATION_SERVER_RESULT_CANNOT_DECODE.get(
265                StaticUtils.getExceptionMessage(e)),
266           e);
267    }
268
269    if (resultCode == null)
270    {
271      throw new LDAPException(ResultCode.DECODING_ERROR,
272           ERR_ASSURED_REPLICATION_SERVER_RESULT_NO_RESULT_CODE.get());
273    }
274
275    return new AssuredReplicationServerResult(resultCode, serverID, replicaID);
276  }
277
278
279
280  /**
281   * Retrieves a string representation of this assured replication server
282   * result.
283   *
284   * @return  A string representation of this assured replication server
285   *          result.
286   */
287  @Override()
288  public String toString()
289  {
290    final StringBuilder buffer = new StringBuilder();
291    toString(buffer);
292    return buffer.toString();
293  }
294
295
296
297  /**
298   * Appends a string representation of this assured replication server result
299   * to the provided buffer.
300   *
301   * @param  buffer  The buffer to which the information should be appended.
302   */
303  public void toString(final StringBuilder buffer)
304  {
305    buffer.append("AssuredReplicationServerResult(resultCode=");
306    buffer.append(resultCode.name());
307
308    if (replicationServerID != null)
309    {
310      buffer.append(", replicationServerID=");
311      buffer.append(replicationServerID);
312    }
313
314    if (replicaID != null)
315    {
316      buffer.append(", replicaID=");
317      buffer.append(replicaID);
318    }
319
320    buffer.append(')');
321  }
322}