001/*
002 * Copyright 2013-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2013-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) 2013-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 com.unboundid.asn1.ASN1Element;
041import com.unboundid.asn1.ASN1OctetString;
042import com.unboundid.asn1.ASN1Sequence;
043import com.unboundid.ldap.sdk.Control;
044import com.unboundid.ldap.sdk.ExtendedRequest;
045import com.unboundid.ldap.sdk.ExtendedResult;
046import com.unboundid.ldap.sdk.LDAPConnection;
047import com.unboundid.ldap.sdk.LDAPException;
048import com.unboundid.ldap.sdk.ResultCode;
049import com.unboundid.util.Debug;
050import com.unboundid.util.NotNull;
051import com.unboundid.util.Nullable;
052import com.unboundid.util.StaticUtils;
053import com.unboundid.util.ThreadSafety;
054import com.unboundid.util.ThreadSafetyLevel;
055import com.unboundid.util.Validator;
056
057import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
058
059
060
061/**
062 * This class provides an implementation of an extended request that can be used
063 * to retrieve backup compatibility data for a Directory Server backend.  This
064 * includes both a token that can be used to compare compatibility data with
065 * other servers (or potentially the same server at a later date, for example
066 * to check compatibility after upgrading to a new version), and a set of
067 * capability strings that may provide additional context about how the backup
068 * descriptor may be used.
069 * <BR>
070 * <BLOCKQUOTE>
071 *   <B>NOTE:</B>  This class, and other classes within the
072 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
073 *   supported for use against Ping Identity, UnboundID, and
074 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
075 *   for proprietary functionality or for external specifications that are not
076 *   considered stable or mature enough to be guaranteed to work in an
077 *   interoperable way with other types of LDAP servers.
078 * </BLOCKQUOTE>
079 * <BR>
080 * The OID for this extended request is 1.3.6.1.4.1.30221.2.6.30.  It must have
081 * a value with the following encoding:
082 * <PRE>
083 *   GetBackupCompatibilityDescriptorRequest ::= SEQUENCE {
084 *        baseDN     [0] OCTET STRING,
085 *        ... }
086 * </PRE>
087 *
088 * @see  GetBackupCompatibilityDescriptorExtendedResult
089 * @see  IdentifyBackupCompatibilityProblemsExtendedRequest
090 */
091@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
092public final class GetBackupCompatibilityDescriptorExtendedRequest
093       extends ExtendedRequest
094{
095  /**
096   * The OID (1.3.6.1.4.1.30221.2.6.30) for the get backup compatibility
097   * descriptor extended request.
098   */
099  @NotNull public static final String
100       GET_BACKUP_COMPATIBILITY_DESCRIPTOR_REQUEST_OID =
101            "1.3.6.1.4.1.30221.2.6.30";
102
103
104
105  /**
106   * The BER type for the base DN element in the value sequence.
107   */
108  private static final byte TYPE_BASE_DN = (byte) 0x80;
109
110
111
112  /**
113   * The serial version UID for this serializable class.
114   */
115  private static final long serialVersionUID = 8170562432854535935L;
116
117
118
119  // The base DN for the backend for which to obtain the backup compatibility
120  // descriptor.
121  @NotNull private final String baseDN;
122
123
124
125  /**
126   * Creates a new get backup compatibility descriptor extended request with the
127   * provided base DN.
128   *
129   * @param  baseDN    The base DN for the backend for which to obtain the
130   *                   backup compatibility descriptor.  It must not be
131   *                   {@code null}, and should be the base DN of a backend
132   *                   defined in the server.
133   * @param  controls  The set of controls to include in the request.  It may be
134   *                   {@code null} or empty if no controls should be included.
135   */
136  public GetBackupCompatibilityDescriptorExtendedRequest(
137              @NotNull final String baseDN,
138              @Nullable final Control... controls)
139  {
140    super(GET_BACKUP_COMPATIBILITY_DESCRIPTOR_REQUEST_OID, encodeValue(baseDN),
141         controls);
142
143    this.baseDN = baseDN;
144  }
145
146
147
148  /**
149   * Creates a new get backup compatibility descriptor extended request from the
150   * provided generic extended request.
151   *
152   * @param  r  The generic extended request to decode as a get backup
153   *            compatibility descriptor extended request.
154   *
155   * @throws LDAPException  If the provided request cannot be decoded as a get
156   *                        backup compatibility descriptor extended request.
157   */
158  public GetBackupCompatibilityDescriptorExtendedRequest(
159              @NotNull 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_GET_BACKUP_COMPAT_REQUEST_NO_VALUE.get());
169    }
170
171    try
172    {
173      final ASN1Element[] elements =
174           ASN1Sequence.decodeAsSequence(value.getValue()).elements();
175      baseDN = ASN1OctetString.decodeAsOctetString(elements[0]).stringValue();
176    }
177    catch (final Exception e)
178    {
179      Debug.debugException(e);
180      throw new LDAPException(ResultCode.DECODING_ERROR,
181           ERR_GET_BACKUP_COMPAT_REQUEST_ERROR_PARSING_VALUE.get(
182                StaticUtils.getExceptionMessage(e)),
183           e);
184    }
185  }
186
187
188
189  /**
190   * Encodes the provided information into a format suitable for use as the
191   * value of this extended request.
192   *
193   * @param  baseDN  The base DN for the backend for which to obtain the
194   *                 backup compatibility descriptor.  It must not be
195   *                 {@code null}, and should be the base DN of a backend
196   *                 defined in the server.
197   *
198   * @return  The ASN.1 octet string containing the encoded representation of
199   *          the provided information.
200   */
201  @NotNull()
202  private static ASN1OctetString encodeValue(@NotNull final String baseDN)
203  {
204    Validator.ensureNotNull(baseDN);
205
206    final ASN1Sequence valueSequence = new ASN1Sequence(
207         new ASN1OctetString(TYPE_BASE_DN, baseDN));
208    return new ASN1OctetString(valueSequence.encode());
209  }
210
211
212
213  /**
214   * Retrieves the base DN for the backend for which to obtain the backup
215   * compatibility descriptor.
216   *
217   * @return  The base DN for the backend for which to obtain the backup
218   *          compatibility descriptor.
219   */
220  @NotNull()
221  public String getBaseDN()
222  {
223    return baseDN;
224  }
225
226
227
228  /**
229   * {@inheritDoc}
230   */
231  @Override()
232  @NotNull()
233  public GetBackupCompatibilityDescriptorExtendedResult process(
234              @NotNull final LDAPConnection connection, final int depth)
235         throws LDAPException
236  {
237    final ExtendedResult extendedResponse = super.process(connection, depth);
238    return new GetBackupCompatibilityDescriptorExtendedResult(extendedResponse);
239  }
240
241
242
243  /**
244   * {@inheritDoc}
245   */
246  @Override()
247  @NotNull()
248  public GetBackupCompatibilityDescriptorExtendedRequest duplicate()
249  {
250    return duplicate(getControls());
251  }
252
253
254
255  /**
256   * {@inheritDoc}
257   */
258  @Override()
259  @NotNull()
260  public GetBackupCompatibilityDescriptorExtendedRequest duplicate(
261              @Nullable final Control[] controls)
262  {
263    final GetBackupCompatibilityDescriptorExtendedRequest r =
264         new GetBackupCompatibilityDescriptorExtendedRequest(baseDN, controls);
265    r.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
266    r.setIntermediateResponseListener(getIntermediateResponseListener());
267    r.setReferralDepth(getReferralDepth());
268    r.setReferralConnector(getReferralConnectorInternal());
269    return r;
270  }
271
272
273
274  /**
275   * {@inheritDoc}
276   */
277  @Override()
278  @NotNull()
279  public String getExtendedRequestName()
280  {
281    return INFO_EXTENDED_REQUEST_NAME_GET_BACKUP_COMPAT.get();
282  }
283
284
285
286  /**
287   * {@inheritDoc}
288   */
289  @Override()
290  public void toString(@NotNull final StringBuilder buffer)
291  {
292    buffer.append("GetBackupCompatibilityDescriptorExtendedRequest(baseDN='");
293    buffer.append(baseDN);
294    buffer.append('\'');
295
296    final Control[] controls = getControls();
297    if (controls.length > 0)
298    {
299      buffer.append(", controls={");
300      for (int i=0; i < controls.length; i++)
301      {
302        if (i > 0)
303        {
304          buffer.append(", ");
305        }
306
307        buffer.append(controls[i]);
308      }
309      buffer.append('}');
310    }
311
312    buffer.append(')');
313  }
314}