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.util.ArrayList; 026 027import com.unboundid.asn1.ASN1Element; 028import com.unboundid.asn1.ASN1Null; 029import com.unboundid.asn1.ASN1OctetString; 030import com.unboundid.asn1.ASN1Sequence; 031import com.unboundid.ldap.sdk.Control; 032import com.unboundid.ldap.sdk.ExtendedRequest; 033import com.unboundid.ldap.sdk.ExtendedResult; 034import com.unboundid.ldap.sdk.LDAPConnection; 035import com.unboundid.ldap.sdk.LDAPException; 036import com.unboundid.ldap.sdk.ResultCode; 037import com.unboundid.util.Debug; 038import com.unboundid.util.StaticUtils; 039import com.unboundid.util.ThreadSafety; 040import com.unboundid.util.ThreadSafetyLevel; 041import com.unboundid.util.Validator; 042 043import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 044 045 046 047/** 048 * This class provides an implementation of an extended request that can be used 049 * to retrieve a version of the server configuration. It may be the active 050 * configuration, the baseline configuration, or any of the archived 051 * configurations. The set of available configurations that may be retrieved 052 * can be obtained using the {@link ListConfigurationsExtendedRequest}. 053 * <BR> 054 * <BLOCKQUOTE> 055 * <B>NOTE:</B> This class, and other classes within the 056 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 057 * supported for use against Ping Identity, UnboundID, and 058 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 059 * for proprietary functionality or for external specifications that are not 060 * considered stable or mature enough to be guaranteed to work in an 061 * interoperable way with other types of LDAP servers. 062 * </BLOCKQUOTE> 063 * <BR> 064 * The OID for this extended request is 1.3.6.1.4.1.30221.2.6.28. It must have 065 * a value with the following encoding: 066 * <PRE> 067 * GetConfigurationRequest ::= SEQUENCE { 068 * requestType CHOICE { 069 * activeConfiguration [0] NULL, 070 * baselineConfiguration [1] OCTET STRING, 071 * archivedConfiguration [2] OCTET STRING, 072 * ... }, 073 * ... } 074 * </PRE> 075 */ 076@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 077public final class GetConfigurationExtendedRequest 078 extends ExtendedRequest 079{ 080 /** 081 * The OID (1.3.6.1.4.1.30221.2.6.28) for the get configuration extended 082 * request. 083 */ 084 public static final String GET_CONFIG_REQUEST_OID = 085 "1.3.6.1.4.1.30221.2.6.28"; 086 087 088 089 /** 090 * The serial version UID for this serializable class. 091 */ 092 private static final long serialVersionUID = 2953462215986675988L; 093 094 095 096 // The type of configuration that should be retrieved. 097 private final GetConfigurationType configurationType; 098 099 // The name of the configuration file that should be retrieved. 100 private final String fileName; 101 102 103 104 /** 105 * Creates a new get configuration extended request that has been decoded from 106 * the provided generic extended request. 107 * 108 * @param r The generic extended request to decode as a get configuration 109 * extended request. 110 * 111 * @throws LDAPException If the provided request cannot be decoded as a get 112 * configuration extended request. 113 */ 114 public GetConfigurationExtendedRequest(final ExtendedRequest r) 115 throws LDAPException 116 { 117 super(r); 118 119 final ASN1OctetString value = r.getValue(); 120 if (value == null) 121 { 122 throw new LDAPException(ResultCode.DECODING_ERROR, 123 ERR_GET_CONFIG_REQUEST_NO_VALUE.get()); 124 } 125 126 try 127 { 128 final ASN1Element[] elements = 129 ASN1Sequence.decodeAsSequence(value.getValue()).elements(); 130 switch (elements[0].getType()) 131 { 132 case GetConfigurationType.ACTIVE_BER_TYPE: 133 configurationType = GetConfigurationType.ACTIVE; 134 fileName = null; 135 break; 136 case GetConfigurationType.BASELINE_BER_TYPE: 137 configurationType = GetConfigurationType.BASELINE; 138 fileName = 139 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 140 break; 141 case GetConfigurationType.ARCHIVED_BER_TYPE: 142 configurationType = GetConfigurationType.ARCHIVED; 143 fileName = 144 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 145 break; 146 default: 147 throw new LDAPException(ResultCode.DECODING_ERROR, 148 ERR_GET_CONFIG_REQUEST_UNEXPECTED_CONFIG_TYPE.get( 149 StaticUtils.toHex(elements[0].getType()))); 150 } 151 } 152 catch (final LDAPException le) 153 { 154 Debug.debugException(le); 155 throw le; 156 } 157 catch (final Exception e) 158 { 159 Debug.debugException(e); 160 throw new LDAPException(ResultCode.DECODING_ERROR, 161 ERR_GET_CONFIG_REQUEST_ERROR_PARSING_VALUE.get( 162 StaticUtils.getExceptionMessage(e)), 163 e); 164 } 165 } 166 167 168 169 /** 170 * Creates a new get configuration extended request with the provided 171 * information. 172 * 173 * @param configurationType The type of configuration that should be 174 * retrieved. 175 * @param fileName The name of the configuration file that should 176 * be retrieved, if appropriate. 177 * @param controls An optional set of controls to include in the 178 * request. This may be {@code null} or empty if 179 * no controls should be included in the request. 180 */ 181 private GetConfigurationExtendedRequest( 182 final GetConfigurationType configurationType, 183 final String fileName, final Control... controls) 184 { 185 super(GET_CONFIG_REQUEST_OID, encodeValue(configurationType, fileName), 186 controls); 187 188 this.configurationType = configurationType; 189 this.fileName = fileName; 190 } 191 192 193 194 /** 195 * Encodes the provided information into a format suitable for use as the 196 * value of this extended request. 197 * 198 * @param configurationType The type of configuration that should be 199 * retrieved. 200 * @param fileName The name of the configuration file that should 201 * be retrieved, if appropriate. 202 * 203 * @return The ASN.1 octet string containing the encoded representation of 204 * the provided information. 205 */ 206 private static ASN1OctetString encodeValue( 207 final GetConfigurationType configurationType, 208 final String fileName) 209 { 210 final ArrayList<ASN1Element> elements = new ArrayList<>(0); 211 switch (configurationType) 212 { 213 case ACTIVE: 214 elements.add(new ASN1Null(configurationType.getBERType())); 215 break; 216 217 case BASELINE: 218 case ARCHIVED: 219 elements.add( 220 new ASN1OctetString(configurationType.getBERType(), fileName)); 221 break; 222 223 default: 224 // This should never happen. 225 return null; 226 } 227 228 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 229 } 230 231 232 233 /** 234 * Creates a new get configuration extended request that may be used to 235 * retrieve the current active configuration. 236 * 237 * @param controls An optional set of controls to include in the request. 238 * This may be {@code null} or empty if no controls should 239 * be included in the request. 240 * 241 * @return The get configuration extended request that has been created. 242 */ 243 public static GetConfigurationExtendedRequest 244 createGetActiveConfigurationRequest( 245 final Control... controls) 246 { 247 return new GetConfigurationExtendedRequest(GetConfigurationType.ACTIVE, 248 null, controls); 249 } 250 251 252 253 /** 254 * Creates a new get configuration extended request that may be used to 255 * retrieve the baseline configuration for the current server version. 256 * 257 * @param fileName The name of the archived configuration file to retrieve. 258 * This must not be {@code null}. 259 * @param controls An optional set of controls to include in the request. 260 * This may be {@code null} or empty if no controls should 261 * be included in the request. 262 * 263 * @return The get configuration extended request that has been created. 264 */ 265 public static GetConfigurationExtendedRequest 266 createGetBaselineConfigurationRequest( 267 final String fileName, final Control... controls) 268 { 269 Validator.ensureNotNull(fileName); 270 271 return new GetConfigurationExtendedRequest(GetConfigurationType.BASELINE, 272 fileName, controls); 273 } 274 275 276 277 /** 278 * Creates a new get configuration extended request that may be used to 279 * retrieve the baseline configuration for the current server version. 280 * 281 * @param fileName The name of the archived configuration file to retrieve. 282 * This must not be {@code null}. 283 * @param controls An optional set of controls to include in the request. 284 * This may be {@code null} or empty if no controls should 285 * be included in the request. 286 * 287 * @return The get configuration extended request that has been created. 288 */ 289 public static GetConfigurationExtendedRequest 290 createGetArchivedConfigurationRequest( 291 final String fileName, final Control... controls) 292 { 293 Validator.ensureNotNull(fileName); 294 295 return new GetConfigurationExtendedRequest(GetConfigurationType.ARCHIVED, 296 fileName, controls); 297 } 298 299 300 301 /** 302 * Retrieves the type of configuration file that should be requested. 303 * 304 * @return The type of configuration file that should be requested. 305 */ 306 public GetConfigurationType getConfigurationType() 307 { 308 return configurationType; 309 } 310 311 312 313 /** 314 * Retrieves the name of the configuration file that should be requested, if 315 * applicable. This will only be available for requests that intend to 316 * retrieve a baseline or archived configuration. 317 * 318 * @return The name of the configuration file that should be requested, or 319 * {@code null} if this is not applicable. 320 */ 321 public String getFileName() 322 { 323 return fileName; 324 } 325 326 327 328 /** 329 * {@inheritDoc} 330 */ 331 @Override() 332 public GetConfigurationExtendedResult process( 333 final LDAPConnection connection, final int depth) 334 throws LDAPException 335 { 336 final ExtendedResult extendedResponse = super.process(connection, depth); 337 return new GetConfigurationExtendedResult(extendedResponse); 338 } 339 340 341 342 /** 343 * {@inheritDoc} 344 */ 345 @Override() 346 public GetConfigurationExtendedRequest duplicate() 347 { 348 return duplicate(getControls()); 349 } 350 351 352 353 /** 354 * {@inheritDoc} 355 */ 356 @Override() 357 public GetConfigurationExtendedRequest duplicate(final Control[] controls) 358 { 359 final GetConfigurationExtendedRequest r = 360 new GetConfigurationExtendedRequest(configurationType, fileName, 361 controls); 362 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 363 return r; 364 } 365 366 367 368 /** 369 * {@inheritDoc} 370 */ 371 @Override() 372 public String getExtendedRequestName() 373 { 374 return INFO_EXTENDED_REQUEST_NAME_GET_CONFIG.get(); 375 } 376 377 378 379 /** 380 * {@inheritDoc} 381 */ 382 @Override() 383 public void toString(final StringBuilder buffer) 384 { 385 buffer.append("GetConfigurationsExtendedRequest(configType="); 386 buffer.append(configurationType.name()); 387 388 if (fileName != null) 389 { 390 buffer.append(", fileName='"); 391 buffer.append(fileName); 392 buffer.append('\''); 393 } 394 395 final Control[] controls = getControls(); 396 if (controls.length > 0) 397 { 398 buffer.append(", controls={"); 399 for (int i=0; i < controls.length; i++) 400 { 401 if (i > 0) 402 { 403 buffer.append(", "); 404 } 405 406 buffer.append(controls[i]); 407 } 408 buffer.append('}'); 409 } 410 411 buffer.append(')'); 412 } 413}