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 java.io.ByteArrayInputStream; 026import java.io.InputStream; 027 028import com.unboundid.asn1.ASN1Element; 029import com.unboundid.asn1.ASN1Enumerated; 030import com.unboundid.asn1.ASN1OctetString; 031import com.unboundid.asn1.ASN1Sequence; 032import com.unboundid.ldap.sdk.Control; 033import com.unboundid.ldap.sdk.ExtendedResult; 034import com.unboundid.ldap.sdk.LDAPException; 035import com.unboundid.ldap.sdk.ResultCode; 036import com.unboundid.util.Debug; 037import com.unboundid.util.StaticUtils; 038import com.unboundid.util.ThreadSafety; 039import com.unboundid.util.ThreadSafetyLevel; 040import com.unboundid.util.Validator; 041 042import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 043 044 045 046/** 047 * This class provides an implementation of an extended result that can be used 048 * to retrieve a version of the server configuration. 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 * <BR> 060 * The OID for this extended result is 1.3.6.1.4.1.30221.2.6.29. If the request 061 * was processed successfully, then the response will have a value with the 062 * following encoding: 063 * <PRE> 064 * GetConfigurationResult ::= SEQUENCE { 065 * configurationType [0] ENUMERATED { 066 * active (0), 067 * baseline (1), 068 * archived (2), 069 * ... }, 070 * fileName [1] OCTET STRING, 071 * configurationFileData [2] OCTET STRING, 072 * ... } 073 * </PRE> 074 * 075 * @see GetConfigurationExtendedRequest 076 * @see ListConfigurationsExtendedRequest 077 */ 078@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 079public final class GetConfigurationExtendedResult 080 extends ExtendedResult 081{ 082 /** 083 * The OID (1.3.6.1.4.1.30221.2.6.29) for the get configuration extended 084 * result. 085 */ 086 public static final String GET_CONFIG_RESULT_OID = "1.3.6.1.4.1.30221.2.6.29"; 087 088 089 090 /** 091 * The BER type for the element holding the type of configuration that has 092 * been returned. 093 */ 094 private static final byte TYPE_CONFIG_TYPE = (byte) 0x80; 095 096 097 098 /** 099 * The BER type for the element holding the name of the configuration file 100 * that has been returned. 101 */ 102 private static final byte TYPE_FILE_NAME = (byte) 0x81; 103 104 105 106 /** 107 * The BER type for the element holding the raw LDIF data that comprises the 108 * configuration file that has been returned. 109 */ 110 private static final byte TYPE_FILE_DATA = (byte) 0x82; 111 112 113 114 /** 115 * The serial version UID for this serializable class. 116 */ 117 private static final long serialVersionUID = 6042324433827773678L; 118 119 120 121 // The raw data for the configuration file that has been returned. 122 private final byte[] fileData; 123 124 // The type of configuration that has been returned. 125 private final GetConfigurationType configurationType; 126 127 // The name of the configuration file that has been returned. 128 private final String fileName; 129 130 131 132 /** 133 * Creates a new get configuration extended result from the provided generic 134 * extended result. 135 * 136 * @param result The generic extended result to be decoded as a get 137 * configuration extended result. 138 * 139 * @throws LDAPException If the provided extended result cannot be parsed as 140 * a valid get configuration extended result. 141 */ 142 public GetConfigurationExtendedResult(final ExtendedResult result) 143 throws LDAPException 144 { 145 super(result); 146 147 final ASN1OctetString value = result.getValue(); 148 if (value == null) 149 { 150 configurationType = null; 151 fileName = null; 152 fileData = null; 153 return; 154 } 155 156 try 157 { 158 final ASN1Element[] elements = 159 ASN1Sequence.decodeAsSequence(value.getValue()).elements(); 160 161 final int configType = 162 ASN1Enumerated.decodeAsEnumerated(elements[0]).intValue(); 163 configurationType = GetConfigurationType.forIntValue(configType); 164 if (configurationType == null) 165 { 166 throw new LDAPException(ResultCode.DECODING_ERROR, 167 ERR_GET_CONFIG_RESULT_INVALID_CONFIG_TYPE.get(configType)); 168 } 169 170 fileName = ASN1OctetString.decodeAsOctetString(elements[1]).stringValue(); 171 fileData = ASN1OctetString.decodeAsOctetString(elements[2]).getValue(); 172 } 173 catch (final LDAPException le) 174 { 175 Debug.debugException(le); 176 throw le; 177 } 178 catch (final Exception e) 179 { 180 Debug.debugException(e); 181 throw new LDAPException(ResultCode.DECODING_ERROR, 182 ERR_GET_CONFIG_RESULT_ERROR_PARSING_VALUE.get( 183 StaticUtils.getExceptionMessage(e)), 184 e); 185 } 186 } 187 188 189 190 /** 191 * Creates a new get configuration extended result with the provided 192 * information. 193 * 194 * @param messageID The message ID for the LDAP message that is 195 * associated with this LDAP result. 196 * @param resultCode The result code from the response. 197 * @param diagnosticMessage The diagnostic message from the response, if 198 * available. 199 * @param matchedDN The matched DN from the response, if available. 200 * @param referralURLs The set of referral URLs from the response, if 201 * available. 202 * @param configurationType The type of configuration that has been 203 * returned. 204 * @param fileName The name of the configuration file that has been 205 * returned. 206 * @param fileData The raw data for the configuration file that has 207 * been returned. 208 * @param responseControls The set of controls from the response, if 209 * available. 210 */ 211 public GetConfigurationExtendedResult(final int messageID, 212 final ResultCode resultCode, final String diagnosticMessage, 213 final String matchedDN, final String[] referralURLs, 214 final GetConfigurationType configurationType, 215 final String fileName, final byte[] fileData, 216 final Control... responseControls) 217 { 218 super(messageID, resultCode, diagnosticMessage, matchedDN, referralURLs, 219 ((configurationType == null) ? null : GET_CONFIG_RESULT_OID), 220 encodeValue(configurationType, fileName, fileData), responseControls); 221 222 this.configurationType = configurationType; 223 this.fileName = fileName; 224 this.fileData = fileData; 225 } 226 227 228 229 /** 230 * Creates an ASN.1 octet string containing an encoded representation of the 231 * value for a get configuration extended result with the provided 232 * information. 233 * 234 * @param configurationType The type of configuration that has been 235 * returned. 236 * @param fileName The name of the configuration file that has been 237 * returned. 238 * @param fileData The raw data for the configuration file that has 239 * been returned. 240 * 241 * @return An ASN.1 octet string containing an encoded representation of the 242 * value for a get configuration extended result, or {@code null} if 243 * a result with the provided information should not have a value. 244 */ 245 public static ASN1OctetString encodeValue( 246 final GetConfigurationType configurationType, 247 final String fileName, final byte[] fileData) 248 { 249 if (configurationType == null) 250 { 251 Validator.ensureTrue((fileName == null), 252 "The configuration file name must be null if the configuration " + 253 "type is null."); 254 Validator.ensureTrue((fileData == null), 255 "The configuration file data must be null if the configuration " + 256 "type is null."); 257 return null; 258 } 259 260 Validator.ensureTrue((fileName != null), 261 "The configuration file name must not be null if the configuration " + 262 "type is not null."); 263 Validator.ensureTrue((fileData != null), 264 "The configuration file data must not be null if the configuration " + 265 "type is not null."); 266 267 final ASN1Sequence valueSequence = new ASN1Sequence( 268 new ASN1Enumerated(TYPE_CONFIG_TYPE, configurationType.getIntValue()), 269 new ASN1OctetString(TYPE_FILE_NAME, fileName), 270 new ASN1OctetString(TYPE_FILE_DATA, fileData)); 271 return new ASN1OctetString(valueSequence.encode()); 272 } 273 274 275 276 /** 277 * Retrieves the type of configuration that has been returned, if available. 278 * 279 * @return The type of configuration that has been returned, or {@code null} 280 * if this is not available. 281 */ 282 public GetConfigurationType getConfigurationType() 283 { 284 return configurationType; 285 } 286 287 288 289 /** 290 * Retrieves the name of the configuration file that has been returned, if 291 * available. 292 * 293 * @return The name of the configuration file that has been returned, or 294 * {@code null} if this is not available. 295 */ 296 public String getFileName() 297 { 298 return fileName; 299 } 300 301 302 303 /** 304 * Retrieves the raw data for the configuration file that has been returned, 305 * if available. 306 * 307 * @return The raw data for the configuration file that has been returned, 308 * or {@code null} if this is not available. 309 */ 310 public byte[] getFileData() 311 { 312 return fileData; 313 } 314 315 316 317 /** 318 * Retrieves an input stream that may be used to read the file data that has 319 * been returned, if available. 320 * 321 * @return An input stream that may be used to read the file data that has 322 * been returned, or {@code null} if this is not available. 323 */ 324 public InputStream getFileDataInputStream() 325 { 326 if (fileData == null) 327 { 328 return null; 329 } 330 else 331 { 332 return new ByteArrayInputStream(fileData); 333 } 334 } 335 336 337 338 /** 339 * {@inheritDoc} 340 */ 341 @Override() 342 public String getExtendedResultName() 343 { 344 return INFO_EXTENDED_RESULT_NAME_GET_CONFIG.get(); 345 } 346 347 348 349 /** 350 * {@inheritDoc} 351 */ 352 @Override() 353 public void toString(final StringBuilder buffer) 354 { 355 buffer.append("GetConfigurationExtendedResult(resultCode="); 356 buffer.append(getResultCode()); 357 358 final int messageID = getMessageID(); 359 if (messageID >= 0) 360 { 361 buffer.append(", messageID="); 362 buffer.append(messageID); 363 } 364 365 if (configurationType != null) 366 { 367 buffer.append(", configType="); 368 buffer.append(configurationType.name()); 369 } 370 371 if (fileName != null) 372 { 373 buffer.append(", fileName='"); 374 buffer.append(fileName); 375 buffer.append('\''); 376 } 377 378 if (fileData != null) 379 { 380 buffer.append(", fileLength="); 381 buffer.append(fileData.length); 382 } 383 384 final String diagnosticMessage = getDiagnosticMessage(); 385 if (diagnosticMessage != null) 386 { 387 buffer.append(", diagnosticMessage='"); 388 buffer.append(diagnosticMessage); 389 buffer.append('\''); 390 } 391 392 final String matchedDN = getMatchedDN(); 393 if (matchedDN != null) 394 { 395 buffer.append(", matchedDN='"); 396 buffer.append(matchedDN); 397 buffer.append('\''); 398 } 399 400 final String[] referralURLs = getReferralURLs(); 401 if (referralURLs.length > 0) 402 { 403 buffer.append(", referralURLs={"); 404 for (int i=0; i < referralURLs.length; i++) 405 { 406 if (i > 0) 407 { 408 buffer.append(", "); 409 } 410 411 buffer.append('\''); 412 buffer.append(referralURLs[i]); 413 buffer.append('\''); 414 } 415 buffer.append('}'); 416 } 417 418 final Control[] responseControls = getResponseControls(); 419 if (responseControls.length > 0) 420 { 421 buffer.append(", responseControls={"); 422 for (int i=0; i < responseControls.length; i++) 423 { 424 if (i > 0) 425 { 426 buffer.append(", "); 427 } 428 429 buffer.append(responseControls[i]); 430 } 431 buffer.append('}'); 432 } 433 434 buffer.append(')'); 435 } 436}