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.extensions;
022
023
024
025import com.unboundid.asn1.ASN1Element;
026import com.unboundid.asn1.ASN1OctetString;
027import com.unboundid.asn1.ASN1Sequence;
028import com.unboundid.ldap.sdk.Control;
029import com.unboundid.ldap.sdk.ExtendedRequest;
030import com.unboundid.ldap.sdk.ExtendedResult;
031import com.unboundid.ldap.sdk.LDAPConnection;
032import com.unboundid.ldap.sdk.LDAPException;
033import com.unboundid.ldap.sdk.ResultCode;
034import com.unboundid.util.Debug;
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 an implementation of an extended request that can be used
046 * to identify potential incompatibility problems between two backup
047 * compatibility descriptor values.  This can be used to determine whether a
048 * backup from one server (or an older version of the same server) could be
049 * restored into another server (or a newer version of the same server).  It
050 * may also be useful in determining whether replication initialization via
051 * binary copy may be performed between two servers.
052 * <BR>
053 * <BLOCKQUOTE>
054 *   <B>NOTE:</B>  This class, and other classes within the
055 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
056 *   supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661
057 *   server products.  These classes provide support for proprietary
058 *   functionality or for external specifications that are not considered stable
059 *   or mature enough to be guaranteed to work in an interoperable way with
060 *   other types of LDAP servers.
061 * </BLOCKQUOTE>
062 * <BR>
063 * The OID for this extended request is 1.3.6.1.4.1.30221.2.6.32.  It must have
064 * a value with the following encoding:
065 * <PRE>
066 *   IdentifyBackupCompatibilityProblemsRequest ::= SEQUENCE {
067 *        sourceDescriptor     [0] OCTET STRING,
068 *        targetDescriptor     [1] OCTET STRING,
069 *        ... }
070 * </PRE>
071 *
072 * @see  IdentifyBackupCompatibilityProblemsExtendedResult
073 * @see  GetBackupCompatibilityDescriptorExtendedRequest
074 */
075@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
076public final class IdentifyBackupCompatibilityProblemsExtendedRequest
077       extends ExtendedRequest
078{
079  /**
080   * The OID (1.3.6.1.4.1.30221.2.6.32) for the identify backup compatibility
081   * problems extended request.
082   */
083  public static final String
084       IDENTIFY_BACKUP_COMPATIBILITY_PROBLEMS_REQUEST_OID =
085            "1.3.6.1.4.1.30221.2.6.32";
086
087
088
089  /**
090   * The BER type for the source descriptor element in the value sequence.
091   */
092  private static final byte TYPE_SOURCE_DESCRIPTOR = (byte) 0x80;
093
094
095
096  /**
097   * The BER type for the target descriptor element in the value sequence.
098   */
099  private static final byte TYPE_TARGET_DESCRIPTOR = (byte) 0x81;
100
101
102
103  /**
104   * The serial version UID for this serializable class.
105   */
106  private static final long serialVersionUID = 6723590129573376599L;
107
108
109
110  // The backup compatibility descriptor obtained from the source server, or
111  // from a backup to be restored.
112  private final ASN1OctetString sourceDescriptor;
113
114  // The backup compatibility descriptor obtained from the target server.
115  private final ASN1OctetString targetDescriptor;
116
117
118
119  /**
120   * Creates a new identify backup compatibility problems extended request with
121   * the provided information.
122   *
123   * @param  sourceDescriptor  The backup compatibility descriptor obtained from
124   *                           the source server, or from a backup to be
125   *                           restored.  It must not be {@code null}.
126   * @param  targetDescriptor  The backup compatibility descriptor obtained from
127   *                           the target server.  It must not be {@code null}.
128   * @param  controls          The set of controls to include in the request.
129   *                           It may be {@code null} or empty if no controls
130   *                           should be included.
131   */
132  public IdentifyBackupCompatibilityProblemsExtendedRequest(
133       final ASN1OctetString sourceDescriptor,
134       final ASN1OctetString targetDescriptor, final Control... controls)
135  {
136    super(IDENTIFY_BACKUP_COMPATIBILITY_PROBLEMS_REQUEST_OID,
137         encodeValue(sourceDescriptor, targetDescriptor), controls);
138
139    this.sourceDescriptor = new ASN1OctetString(TYPE_SOURCE_DESCRIPTOR,
140         sourceDescriptor.getValue());
141    this.targetDescriptor = new ASN1OctetString(TYPE_TARGET_DESCRIPTOR,
142         targetDescriptor.getValue());
143  }
144
145
146
147  /**
148   * Creates a new identify backup compatibility problems extended request from
149   * the provided generic extended request.
150   *
151   * @param  r  The generic extended request to decode as an identify backup
152   *            compatibility problems extended request.
153   *
154   * @throws LDAPException  If the provided request cannot be decoded as an
155   *                        identify backup compatibility problems extended
156   *                        request.
157   */
158  public IdentifyBackupCompatibilityProblemsExtendedRequest(
159       final ExtendedRequest r)
160       throws LDAPException
161  {
162    super(r);
163
164    final ASN1OctetString value = r.getValue();
165    if (value == null)
166    {
167      throw new LDAPException(ResultCode.DECODING_ERROR,
168           ERR_IDENTIFY_BACKUP_COMPAT_PROBLEMS_REQUEST_NO_VALUE.get());
169    }
170
171    try
172    {
173      final ASN1Element[] elements =
174           ASN1Sequence.decodeAsSequence(value.getValue()).elements();
175      sourceDescriptor =
176           new ASN1OctetString(TYPE_SOURCE_DESCRIPTOR, elements[0].getValue());
177      targetDescriptor =
178           new ASN1OctetString(TYPE_SOURCE_DESCRIPTOR, elements[1].getValue());
179    }
180    catch (final Exception e)
181    {
182      Debug.debugException(e);
183      throw new LDAPException(ResultCode.DECODING_ERROR,
184           ERR_IDENTIFY_BACKUP_COMPAT_PROBLEMS_REQUEST_ERROR_PARSING_VALUE.get(
185                StaticUtils.getExceptionMessage(e)),
186           e);
187    }
188  }
189
190
191
192  /**
193   * Encodes the provided information into a format suitable for use as the
194   * value of this extended request.
195   *
196   * @param  sourceDescriptor  The backup compatibility descriptor obtained from
197   *                           the source server, or from a backup to be
198   *                           restored.  It must not be {@code null}.
199   * @param  targetDescriptor  The backup compatibility descriptor obtained from
200   *                           the target server.  It must not be {@code null}.
201   *
202   * @return  The ASN.1 octet string containing the encoded representation of
203   *          the provided information.
204   */
205  private static ASN1OctetString encodeValue(
206                                      final ASN1OctetString sourceDescriptor,
207                                      final ASN1OctetString targetDescriptor)
208  {
209    Validator.ensureNotNull(sourceDescriptor);
210    Validator.ensureNotNull(targetDescriptor);
211
212    final ASN1Sequence valueSequence = new ASN1Sequence(
213         new ASN1OctetString(TYPE_SOURCE_DESCRIPTOR,
214              sourceDescriptor.getValue()),
215         new ASN1OctetString(TYPE_TARGET_DESCRIPTOR,
216              targetDescriptor.getValue()));
217
218    return new ASN1OctetString(valueSequence.encode());
219  }
220
221
222
223  /**
224   * Retrieves the backup compatibility descriptor obtained from the source
225   * server, or from a backup to be restored.
226   *
227   * @return  The backup compatibility descriptor obtained from the source
228   *          server, or from a backup to be restored.
229   */
230  public ASN1OctetString getSourceDescriptor()
231  {
232    return sourceDescriptor;
233  }
234
235
236
237  /**
238   * Retrieves the backup compatibility descriptor obtained from the target
239   * server.
240   *
241   * @return  The backup compatibility descriptor obtained from the target
242   *          server.
243   */
244  public ASN1OctetString getTargetDescriptor()
245  {
246    return targetDescriptor;
247  }
248
249
250
251  /**
252   * {@inheritDoc}
253   */
254  @Override()
255  public IdentifyBackupCompatibilityProblemsExtendedResult process(
256              final LDAPConnection connection, final int depth)
257         throws LDAPException
258  {
259    final ExtendedResult extendedResponse = super.process(connection, depth);
260    return new IdentifyBackupCompatibilityProblemsExtendedResult(
261         extendedResponse);
262  }
263
264
265
266  /**
267   * {@inheritDoc}
268   */
269  @Override()
270  public IdentifyBackupCompatibilityProblemsExtendedRequest duplicate()
271  {
272    return duplicate(getControls());
273  }
274
275
276
277  /**
278   * {@inheritDoc}
279   */
280  @Override()
281  public IdentifyBackupCompatibilityProblemsExtendedRequest duplicate(
282              final Control[] controls)
283  {
284    final IdentifyBackupCompatibilityProblemsExtendedRequest r =
285         new IdentifyBackupCompatibilityProblemsExtendedRequest(
286              sourceDescriptor, targetDescriptor, controls);
287    r.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
288    return r;
289  }
290
291
292
293  /**
294   * {@inheritDoc}
295   */
296  @Override()
297  public String getExtendedRequestName()
298  {
299    return INFO_EXTENDED_REQUEST_NAME_IDENTIFY_BACKUP_COMPAT_PROBLEMS.get();
300  }
301
302
303
304  /**
305   * {@inheritDoc}
306   */
307  @Override()
308  public void toString(final StringBuilder buffer)
309  {
310    buffer.append("IdentifyBackupCompatibilityProblemsExtendedRequest(" +
311         "sourceDescriptorLength=");
312    buffer.append(sourceDescriptor.getValueLength());
313    buffer.append(", targetDescriptorLength=");
314    buffer.append(targetDescriptor.getValueLength());
315
316    final Control[] controls = getControls();
317    if (controls.length > 0)
318    {
319      buffer.append(", controls={");
320      for (int i=0; i < controls.length; i++)
321      {
322        if (i > 0)
323        {
324          buffer.append(", ");
325        }
326
327        buffer.append(controls[i]);
328      }
329      buffer.append('}');
330    }
331
332    buffer.append(')');
333  }
334}