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 retrieve backup compatibility data for a Directory Server backend. This 053 * includes both a token that can be used to compare compatibility data with 054 * other servers (or potentially the same server at a later date, for example 055 * to check compatibility after upgrading to a new version), and a set of 056 * capability strings that may provide additional context about how the backup 057 * descriptor may be used. 058 * <BR><BR> 059 * The OID for this extended request is 1.3.6.1.4.1.30221.2.6.30. It must have 060 * a value with the following encoding: 061 * <PRE> 062 * GetBackupCompatibilityDescriptorRequest ::= SEQUENCE { 063 * baseDN [0] OCTET STRING, 064 * ... } 065 * </PRE> 066 * 067 * @see GetBackupCompatibilityDescriptorExtendedResult 068 * @see IdentifyBackupCompatibilityProblemsExtendedRequest 069 */ 070 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 071 public final class GetBackupCompatibilityDescriptorExtendedRequest 072 extends ExtendedRequest 073 { 074 /** 075 * The OID (1.3.6.1.4.1.30221.2.6.30) for the get backup compatibility 076 * descriptor extended request. 077 */ 078 public static final String GET_BACKUP_COMPATIBILITY_DESCRIPTOR_REQUEST_OID = 079 "1.3.6.1.4.1.30221.2.6.30"; 080 081 082 083 /** 084 * The BER type for the base DN element in the value sequence. 085 */ 086 private static final byte TYPE_BASE_DN = (byte) 0x80; 087 088 089 090 /** 091 * The serial version UID for this serializable class. 092 */ 093 private static final long serialVersionUID = 8170562432854535935L; 094 095 096 097 // The base DN for the backend for which to obtain the backup compatibility 098 // descriptor. 099 private final String baseDN; 100 101 102 103 /** 104 * Creates a new get backup compatibility descriptor extended request with the 105 * provided base DN. 106 * 107 * @param baseDN The base DN for the backend for which to obtain the 108 * backup compatibility descriptor. It must not be 109 * {@code null}, and should be the base DN of a backend 110 * defined in the server. 111 * @param controls The set of controls to include in the request. It may be 112 * {@code null} or empty if no controls should be included. 113 */ 114 public GetBackupCompatibilityDescriptorExtendedRequest(final String baseDN, 115 final Control... controls) 116 { 117 super(GET_BACKUP_COMPATIBILITY_DESCRIPTOR_REQUEST_OID, encodeValue(baseDN), 118 controls); 119 120 this.baseDN = baseDN; 121 } 122 123 124 125 /** 126 * Creates a new get backup compatibility descriptor extended request from the 127 * provided generic extended request. 128 * 129 * @param r The generic extended request to decode as a get backup 130 * compatibility descriptor extended request. 131 * 132 * @throws LDAPException If the provided request cannot be decoded as a get 133 * backup compatibility descriptor extended request. 134 */ 135 public GetBackupCompatibilityDescriptorExtendedRequest( 136 final ExtendedRequest r) 137 throws LDAPException 138 { 139 super(r); 140 141 final ASN1OctetString value = r.getValue(); 142 if (value == null) 143 { 144 throw new LDAPException(ResultCode.DECODING_ERROR, 145 ERR_GET_BACKUP_COMPAT_REQUEST_NO_VALUE.get()); 146 } 147 148 try 149 { 150 final ASN1Element[] elements = 151 ASN1Sequence.decodeAsSequence(value.getValue()).elements(); 152 baseDN = ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 153 } 154 catch (final Exception e) 155 { 156 Debug.debugException(e); 157 throw new LDAPException(ResultCode.DECODING_ERROR, 158 ERR_GET_BACKUP_COMPAT_REQUEST_ERROR_PARSING_VALUE.get( 159 StaticUtils.getExceptionMessage(e)), 160 e); 161 } 162 } 163 164 165 166 /** 167 * Encodes the provided information into a format suitable for use as the 168 * value of this extended request. 169 * 170 * @param baseDN The base DN for the backend for which to obtain the 171 * backup compatibility descriptor. It must not be 172 * {@code null}, and should be the base DN of a backend 173 * defined in the server. 174 * 175 * @return The ASN.1 octet string containing the encoded representation of 176 * the provided information. 177 */ 178 private static ASN1OctetString encodeValue(final String baseDN) 179 { 180 Validator.ensureNotNull(baseDN); 181 182 final ASN1Sequence valueSequence = new ASN1Sequence( 183 new ASN1OctetString(TYPE_BASE_DN, baseDN)); 184 return new ASN1OctetString(valueSequence.encode()); 185 } 186 187 188 189 /** 190 * Retrieves the base DN for the backend for which to obtain the backup 191 * compatibility descriptor. 192 * 193 * @return The base DN for the backend for which to obtain the backup 194 * compatibility descriptor. 195 */ 196 public String getBaseDN() 197 { 198 return baseDN; 199 } 200 201 202 203 /** 204 * {@inheritDoc} 205 */ 206 @Override() 207 public GetBackupCompatibilityDescriptorExtendedResult process( 208 final LDAPConnection connection, final int depth) 209 throws LDAPException 210 { 211 final ExtendedResult extendedResponse = super.process(connection, depth); 212 return new GetBackupCompatibilityDescriptorExtendedResult(extendedResponse); 213 } 214 215 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override() 221 public GetBackupCompatibilityDescriptorExtendedRequest duplicate() 222 { 223 return duplicate(getControls()); 224 } 225 226 227 228 /** 229 * {@inheritDoc} 230 */ 231 @Override() 232 public GetBackupCompatibilityDescriptorExtendedRequest duplicate( 233 final Control[] controls) 234 { 235 final GetBackupCompatibilityDescriptorExtendedRequest r = 236 new GetBackupCompatibilityDescriptorExtendedRequest(baseDN, controls); 237 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 238 return r; 239 } 240 241 242 243 /** 244 * {@inheritDoc} 245 */ 246 @Override() 247 public String getExtendedRequestName() 248 { 249 return INFO_EXTENDED_REQUEST_NAME_GET_BACKUP_COMPAT.get(); 250 } 251 252 253 254 /** 255 * {@inheritDoc} 256 */ 257 @Override() 258 public void toString(final StringBuilder buffer) 259 { 260 buffer.append("GetBackupCompatibilityDescriptorExtendedRequest(baseDN='"); 261 buffer.append(baseDN); 262 buffer.append('\''); 263 264 final Control[] controls = getControls(); 265 if (controls.length > 0) 266 { 267 buffer.append(", controls={"); 268 for (int i=0; i < controls.length; i++) 269 { 270 if (i > 0) 271 { 272 buffer.append(", "); 273 } 274 275 buffer.append(controls[i]); 276 } 277 buffer.append('}'); 278 } 279 280 buffer.append(')'); 281 } 282 }