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