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