001/*
002 * Copyright 2020-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2020-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2020-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk.unboundidds.extensions;
037
038
039
040import java.io.Serializable;
041
042import com.unboundid.asn1.ASN1OctetString;
043import com.unboundid.ldap.sdk.unboundidds.tasks.CollectSupportDataSecurityLevel;
044import com.unboundid.util.Mutable;
045import com.unboundid.util.NotNull;
046import com.unboundid.util.Nullable;
047import com.unboundid.util.ThreadSafety;
048import com.unboundid.util.ThreadSafetyLevel;
049import com.unboundid.util.Validator;
050
051
052
053/**
054 * This class defines a set of properties that may be used when creating a
055 * {@link CollectSupportDataExtendedRequest}.
056 * <BR>
057 * <BLOCKQUOTE>
058 *   <B>NOTE:</B>  This class, and other classes within the
059 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
060 *   supported for use against Ping Identity, UnboundID, and
061 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
062 *   for proprietary functionality or for external specifications that are not
063 *   considered stable or mature enough to be guaranteed to work in an
064 *   interoperable way with other types of LDAP servers.
065 * </BLOCKQUOTE>
066 */
067@Mutable()
068@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
069public final class CollectSupportDataExtendedRequestProperties
070       implements Serializable
071{
072  /**
073   * The serial version UID for this serializable class.
074   */
075  private static final long serialVersionUID = 5585016444537427389L;
076
077
078
079  // The passphrase to use to encrypt the contents of the support data archive.
080  @Nullable private ASN1OctetString encryptionPassphrase;
081
082  // Indicates whether to include binary files in the support data archive.
083  @Nullable private Boolean includeBinaryFiles;
084
085  // Indicates whether to include expensive data in the support data archive.
086  @Nullable private Boolean includeExpensiveData;
087
088  // Indicates whether to include third-party extension source code in the
089  // support data archive.
090  @Nullable private Boolean includeExtensionSource;
091
092  // Indicates whether to include a replication state dump in the support data
093  // archive.
094  @Nullable private Boolean includeReplicationStateDump;
095
096  // Indicates whether to capture information sequentially rather than in
097  // parallel.
098  @Nullable private Boolean useSequentialMode;
099
100  // The log capture window that indicates how much log content to include in
101  // the support data archive.
102  @Nullable private CollectSupportDataLogCaptureWindow logCaptureWindow;
103
104  // The security level to use for data included in the support data archive.
105  @Nullable private CollectSupportDataSecurityLevel securityLevel;
106
107  // The number of jstacks to include in the support data archive.
108  @Nullable private Integer jstackCount;
109
110  // The maximum size, in bytes, of any support data archive fragment to include
111  // in a collect support data archive fragment intermediate response.
112  @Nullable private Integer maximumFragmentSizeBytes;
113
114  // The port of a backend Directory Server instance to which the collect
115  // support data extended request should be forwarded.
116  @Nullable private Integer proxyToServerPort;
117
118  // The report count to use for sampled metrics.
119  @Nullable private Integer reportCount;
120
121  // The report interval in seconds to use for sampled metrics.
122  @Nullable private Integer reportIntervalSeconds;
123
124  // The name (without any path information) the client intends to use for the
125  // support data archive file.
126  @Nullable private String archiveFileName;
127
128  // A comment to include in the support data archive.
129  @Nullable private String comment;
130
131  // The address of a backend Directory Server to which the collect support data
132  // extended request should be forwarded.
133  @Nullable private String proxyToServerAddress;
134
135
136
137  /**
138   * Creates a new set of collect support data extended request properties
139   * with none of the properties set, indicating that the server should use the
140   * default values for all of them.
141   */
142  public CollectSupportDataExtendedRequestProperties()
143  {
144    encryptionPassphrase = null;
145    includeBinaryFiles = null;
146    includeExpensiveData = null;
147    includeExtensionSource = null;
148    includeReplicationStateDump = null;
149    useSequentialMode = null;
150    logCaptureWindow = null;
151    securityLevel = null;
152    jstackCount = null;
153    maximumFragmentSizeBytes = null;
154    proxyToServerPort = null;
155    reportCount = null;
156    reportIntervalSeconds = null;
157    archiveFileName = null;
158    comment = null;
159    proxyToServerAddress = null;
160  }
161
162
163
164  /**
165   * Creates a new set of collect support data extended request properties
166   * that is a copy of the provided properties.
167   *
168   * @param  properties  The set of properties to duplicate.
169   */
170  public CollectSupportDataExtendedRequestProperties(
171       @NotNull final CollectSupportDataExtendedRequestProperties properties)
172  {
173    encryptionPassphrase = properties.getEncryptionPassphrase();
174    includeBinaryFiles = properties.getIncludeBinaryFiles();
175    includeExpensiveData = properties.getIncludeExpensiveData();
176    includeExtensionSource = properties.getIncludeExtensionSource();
177    includeReplicationStateDump = properties.getIncludeReplicationStateDump();
178    useSequentialMode = properties.getUseSequentialMode();
179    logCaptureWindow = properties.getLogCaptureWindow();
180    securityLevel = properties.getSecurityLevel();
181    jstackCount = properties.getJStackCount();
182    maximumFragmentSizeBytes = properties.getMaximumFragmentSizeBytes();
183    proxyToServerPort = properties.getProxyToServerPort();
184    reportCount = properties.getReportCount();
185    reportIntervalSeconds = properties.getReportIntervalSeconds();
186    archiveFileName = properties.getArchiveFileName();
187    comment = properties.getComment();
188    proxyToServerAddress = properties.getProxyToServerAddress();
189  }
190
191
192
193  /**
194   * Creates a new set of collect support data extended request properties
195   * using the settings from the provided extended request.
196   *
197   * @param  request  The collect support data extended request from which to
198   *                  set the property values.
199   */
200  public CollectSupportDataExtendedRequestProperties(
201       @NotNull final CollectSupportDataExtendedRequest request)
202  {
203    encryptionPassphrase = request.getEncryptionPassphrase();
204    includeBinaryFiles = request.getIncludeBinaryFiles();
205    includeExpensiveData = request.getIncludeExpensiveData();
206    includeExtensionSource = request.getIncludeExtensionSource();
207    includeReplicationStateDump = request.getIncludeReplicationStateDump();
208    useSequentialMode = request.getUseSequentialMode();
209    logCaptureWindow = request.getLogCaptureWindow();
210    securityLevel = request.getSecurityLevel();
211    jstackCount = request.getJStackCount();
212    maximumFragmentSizeBytes = request.getMaximumFragmentSizeBytes();
213    proxyToServerPort = request.getProxyToServerPort();
214    reportCount = request.getReportCount();
215    reportIntervalSeconds = request.getReportIntervalSeconds();
216    archiveFileName = request.getArchiveFileName();
217    comment = request.getComment();
218    proxyToServerAddress = request.getProxyToServerAddress();
219  }
220
221
222
223  /**
224   * Retrieves the name (without any path information) that the client intends
225   * to use for the support data archive file.
226   *
227   * @return  The name (without any path information) that the client intends to
228   *          use for the support data archive file, or {@code null} if the
229   *          server should generate an archive file name.
230   */
231  @Nullable()
232  public String getArchiveFileName()
233  {
234    return archiveFileName;
235  }
236
237
238
239  /**
240   * Specifies the name (without any path information) that the client intends
241   * to use for the support data archive file.
242   *
243   * @param  archiveFileName  The name (without any path information) that the
244   *                          client intends to use for the support data archive
245   *                          file.  It may be {@code null} if the server
246   *                          should generate an archive file name.
247   */
248  public void setArchiveFileName(@Nullable final String archiveFileName)
249  {
250    this.archiveFileName = archiveFileName;
251  }
252
253
254
255  /**
256   * Retrieves the passphrase that should be used to encrypt the contents of the
257   * support data archive.
258   *
259   * @return  The passphrase that should be used to encrypt the contents of the
260   *          support data archive, or {@code null} if the archive should not
261   *          be encrypted.
262   */
263  @Nullable()
264  public ASN1OctetString getEncryptionPassphrase()
265  {
266    return encryptionPassphrase;
267  }
268
269
270
271  /**
272   * Specifies the passphrase that should be used to encrypt the contents of the
273   * support data archive.
274   *
275   * @param  encryptionPassphrase  The passphrase that should be used to
276   *                               encrypt the contents of the support data
277   *                               archive.  It may be {@code null} if the
278   *                               support data archive should not be encrypted.
279   */
280  public void setEncryptionPassphrase(
281                   @Nullable final String encryptionPassphrase)
282  {
283    if (encryptionPassphrase == null)
284    {
285      this.encryptionPassphrase = null;
286    }
287    else
288    {
289      this.encryptionPassphrase = new ASN1OctetString(
290           CollectSupportDataExtendedRequest.TYPE_ENCRYPTION_PASSPHRASE,
291           encryptionPassphrase);
292    }
293  }
294
295
296
297  /**
298   * Specifies the passphrase that should be used to encrypt the contents of the
299   * support data archive.
300   *
301   * @param  encryptionPassphrase  The passphrase that should be used to
302   *                               encrypt the contents of the support data
303   *                               archive.  It may be {@code null} if the
304   *                               support data archive should not be encrypted.
305   */
306  public void setEncryptionPassphrase(
307                   @Nullable final byte[] encryptionPassphrase)
308  {
309    if (encryptionPassphrase == null)
310    {
311      this.encryptionPassphrase = null;
312    }
313    else
314    {
315      this.encryptionPassphrase = new ASN1OctetString(
316           CollectSupportDataExtendedRequest.TYPE_ENCRYPTION_PASSPHRASE,
317           encryptionPassphrase);
318    }
319  }
320
321
322
323  /**
324   * Specifies the passphrase that should be used to encrypt the contents of the
325   * support data archive.
326   *
327   * @param  encryptionPassphrase  The passphrase that should be used to
328   *                               encrypt the contents of the support data
329   *                               archive.  It may be {@code null} if the
330   *                               support data archive should not be encrypted.
331   */
332  public void setEncryptionPassphrase(
333                   @Nullable final ASN1OctetString encryptionPassphrase)
334  {
335    if (encryptionPassphrase == null)
336    {
337      this.encryptionPassphrase = null;
338    }
339    else
340    {
341      this.encryptionPassphrase = new ASN1OctetString(
342           CollectSupportDataExtendedRequest.TYPE_ENCRYPTION_PASSPHRASE,
343           encryptionPassphrase.getValue());
344    }
345  }
346
347
348
349  /**
350   * Retrieves the value of a flag that indicates whether the support data
351   * archive may include data that is potentially expensive to collect and
352   * could affect the performance or responsiveness of the server.
353   *
354   * @return  The value of a flag that indicates whether the support data
355   *          archive may include data that is potentially expensive to collect,
356   *          or {@code null} if the property should not be specified when the
357   *          request is created (in which case the server will use a default
358   *          behavior of excluding expensive data).
359   */
360  @Nullable()
361  public Boolean getIncludeExpensiveData()
362  {
363    return includeExpensiveData;
364  }
365
366
367
368  /**
369   * Specifies the value of a flag that indicates whether the support data
370   * archive may include data that is potentially expensive to collect and could
371   * affect the performance or responsiveness of the server.
372   *
373   * @param  includeExpensiveData  The value of a flag that indicates whether
374   *                               the support data archive may include data
375   *                               that is potentially expensive to collect.  It
376   *                               may be {@code null} if the flag should not be
377   *                               specified when the request is created (in
378   *                               which case the server will use a default
379   *                               behavior of excluding expensive data).
380   */
381  public void setIncludeExpensiveData(
382                   @Nullable final Boolean includeExpensiveData)
383  {
384    this.includeExpensiveData = includeExpensiveData;
385  }
386
387
388
389  /**
390   * Retrieves the value of a flag that indicates whether the support data
391   * archive may include a replication state dump, which may be several
392   * megabytes in size.
393   *
394   * @return  The value of a flag that indicates whether the support data
395   *          archive may include a replication state dump, or {@code null} if
396   *          the property should not be specified when the request is created
397   *          (in which case the server will use a default behavior of
398   *          excluding the state dump).
399   */
400  @Nullable()
401  public Boolean getIncludeReplicationStateDump()
402  {
403    return includeReplicationStateDump;
404  }
405
406
407
408  /**
409   * Specifies the value of a flag that indicates whether the support data
410   * archive may include a replication state dump, which may be several
411   * megabytes in size.
412   *
413   * @param  includeReplicationStateDump  The value of a flag that indicates
414   *                                      whether the support data archive may
415   *                                      include a replication state dump.  It
416   *                                      may be {@code null} if the flag should
417   *                                      not be specified when the request is
418   *                                      created (in which case the server will
419   *                                      use a default behavior of excluding
420   *                                      the state dump).
421   */
422  public void setIncludeReplicationStateDump(
423                   @Nullable final Boolean includeReplicationStateDump)
424  {
425    this.includeReplicationStateDump = includeReplicationStateDump;
426  }
427
428
429
430  /**
431   * Retrieves the value of a flag that indicates whether the support data
432   * archive may include binary files.
433   *
434   * @return  The value of a flag that indicates whether the support data
435   *          archive may include binary files, or {@code null} if the property
436   *          should not be specified when the request is created (in which case
437   *          the server will use a default behavior of excluding binary files).
438   */
439  @Nullable()
440  public Boolean getIncludeBinaryFiles()
441  {
442    return includeBinaryFiles;
443  }
444
445
446
447  /**
448   * Specifies the value of a flag that that indicates whether the support data
449   * archive may include binary files.
450   *
451   * @param  includeBinaryFiles  The value of a flag that indicates whether the
452   *                             support data archive may include binary files.
453   *                             It may be {@code null} if the property should
454   *                             not be specified when the request is created
455   *                             (in which case the server will use a default
456   *                             behavior of excluding binary files).
457   */
458  public void setIncludeBinaryFiles(@Nullable final Boolean includeBinaryFiles)
459  {
460    this.includeBinaryFiles = includeBinaryFiles;
461  }
462
463
464
465  /**
466   * Retrieves the value of a flag that indicates whether the support data
467   * archive should include source code (if available) for any third-party
468   * extensions installed in the server.
469   *
470   * @return  The value of a flag that indicates whether the support data
471   *          archive should include source code (if available) for any
472   *          third-party extensions installed in the server, or {@code null} if
473   *          the property should not be specified when the request is created
474   *          (in which case the server will use a default behavior of excluding
475   *          extension source code).
476   */
477  @Nullable()
478  public Boolean getIncludeExtensionSource()
479  {
480    return includeExtensionSource;
481  }
482
483
484
485  /**
486   * Specifies the value of a flag that indicates whether the support data
487   * archive should include source code (if available) for any third-party
488   * extensions installed in the server.
489   *
490   * @param  includeExtensionSource  The value of a flag that indicates whether
491   *                                 the support data archive should include
492   *                                 source code (if available) for any
493   *                                 third-party extensions in the server.  It
494   *                                 may be {@code null} if the property should
495   *                                 not be specified when the requets is
496   *                                 created (in which case the server will use
497   *                                 a default behavior of excluding extension
498   *                                 source code).
499   */
500  public void setIncludeExtensionSource(
501                   @Nullable final Boolean includeExtensionSource)
502  {
503    this.includeExtensionSource = includeExtensionSource;
504  }
505
506
507
508  /**
509   * Retrieves the value of a flag that indicates whether the server should
510   * collect items for the support data archive in sequential mode rather than
511   * in parallel.  Collecting data in sequential mode may reduce the amount of
512   * memory consumed during the collection process, but it will take longer to
513   * complete.
514   *
515   * @return  The value of a flag that indicates whether the server should
516   *          collect items for the support data archive in sequential mode
517   *          rather than in parallel, or {@code null} if the property should
518   *          not be specified when the request is created (in which case the
519   *          server will default to capturing data in parallel).
520   */
521  @Nullable()
522  public Boolean getUseSequentialMode()
523  {
524    return useSequentialMode;
525  }
526
527
528
529  /**
530   * Specifies the value of a flag that indicates whether the server should
531   * collect items for the support data archive in sequential mode rather than
532   * in parallel.  Collecting data in sequential mode may reduce the amount of
533   * memory consumed during the collection process, but it will take longer to
534   * complete.
535   *
536   * @param  useSequentialMode  The value of a flag that indicates whether the
537   *                            server should collect items for the support data
538   *                            archive in sequential mode rather than in
539   *                            parallel.  It may be {@code null} if the
540   *                            property should not be specified when the
541   *                            request is created (in which case the server
542   *                            will default to capturing data in parallel).
543   */
544  public void setUseSequentialMode(@Nullable final Boolean useSequentialMode)
545  {
546    this.useSequentialMode = useSequentialMode;
547  }
548
549
550
551  /**
552   * Retrieves the security level that should be used to indicate which data
553   * should be obscured, redacted, or omitted from the support data archive.
554   *
555   * @return  The security level that should be used when creating the support
556   *          data archive, or {@code null} if the property should not be
557   *          specified when the request is created (in which case the server
558   *          will use a default security level).
559   */
560  @Nullable()
561  public CollectSupportDataSecurityLevel getSecurityLevel()
562  {
563    return securityLevel;
564  }
565
566
567
568  /**
569   * Specifies the security level that should be used to indicate which data
570   * should be obscured, redacted, or omitted from the support data archive.
571   *
572   * @param  securityLevel  The security level that should be used when creating
573   *                        the support data archive.  It may be {@code null} if
574   *                        the property should not be specified when the
575   *                        request is created (in which case the server will
576   *                        use a default security level).
577   */
578  public void setSecurityLevel(
579       @Nullable final CollectSupportDataSecurityLevel securityLevel)
580  {
581    this.securityLevel = securityLevel;
582  }
583
584
585
586  /**
587   * Retrieves the number of times that the jstack utility should be invoked to
588   * obtain stack traces from all threads in the server.
589   *
590   * @return  The number of times that the jstack utility should be invoked to
591   *          obtain stack traces from all threads in the server, or
592   *          {@code null} if the property should not be specified when the
593   *          request is created (in which case the server will use a default
594   *          count).
595   */
596  @Nullable()
597  public Integer getJStackCount()
598  {
599    return jstackCount;
600  }
601
602
603
604  /**
605   * Specifies the number of times that the jstack utility should be invoked to
606   * obtain stack traces from all threads in the server.
607   *
608   * @param  jstackCount  The number of times that the jstack utility should be
609   *                      invoked to obtain stack traces from all threads in the
610   *                      server.  The value must not be negative, but it may be
611   *                      zero to indicate that the jstack utility should not be
612   *                      invoked.  It may be {@code null} if the property
613   *                      should not be specified when the request is created
614   *                      (in which case the server will use a default count).
615   */
616  public void setJStackCount(@Nullable final Integer jstackCount)
617  {
618    if (jstackCount != null)
619    {
620      Validator.ensureTrue((jstackCount >= 0),
621           "If CollectSupportDataExtendedRequestProperties.jstackCount is " +
622                "non-null, then the value must be greater than or equal to " +
623                "zero.");
624    }
625
626    this.jstackCount = jstackCount;
627  }
628
629
630
631  /**
632   * Retrieves the number of intervals that should be captured from tools that
633   * use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
634   *
635   * @return  The number of intervals that should be captured from tools that
636   *          use interval-based sampling, or {@code null} if the property
637   *          should not be specified when the request is created (in which case
638   *          the server will use a default report count).
639   */
640  @Nullable()
641  public Integer getReportCount()
642  {
643    return reportCount;
644  }
645
646
647
648  /**
649   * Specifies the number of intervals that should be captured form tools that
650   * use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
651   *
652   * @param  reportCount  The number of intervals that should be captured from
653   *                      tools that use interval-based sampling.  The value
654   *                      must not be negative, but it may be zero to indicate
655   *                      that no intervals should be captured.  It may be
656   *                      {@code null} if the property should not be specified
657   *                      when the request is created (in which case the server
658   *                      will use a default report count).
659   */
660  public void setReportCount(@Nullable final Integer reportCount)
661  {
662    if (reportCount != null)
663    {
664      Validator.ensureTrue((reportCount >= 0),
665           "If CollectSupportDataExtendedRequestProperties.reportCount is " +
666                "non-null, then the value must be greater than or equal to " +
667                "zero.");
668    }
669
670    this.reportCount = reportCount;
671  }
672
673
674
675  /**
676   * Retrieves the interval duration in seconds that should be used for tools
677   * that use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
678   *
679   * @return  The interval duration in seconds that should be used for tools
680   *          that use interval-based sampling, or {@code null} if the property
681   *          should not be specified when the request is created (in which case
682   *          the server will use a default report interval).
683   */
684  @Nullable()
685  public Integer getReportIntervalSeconds()
686  {
687    return reportIntervalSeconds;
688  }
689
690
691
692  /**
693   * Specifies the interval duration in seconds that should be used for tools
694   * that use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.).
695   *
696   * @param  reportIntervalSeconds  The interval duration in seconds that should
697   *                                be used for tools that use interval-based
698   *                                sampling.  The value must be greater than or
699   *                                equal to one.  It may be {@code null} if the
700   *                                property should not be specified when the
701   *                                request is created (in which case the server
702   *                                will use a default report count).
703   */
704  public void setReportIntervalSeconds(
705                   @Nullable final Integer reportIntervalSeconds)
706  {
707    if (reportIntervalSeconds != null)
708    {
709      Validator.ensureTrue((reportIntervalSeconds > 0),
710           "If CollectSupportDataExtendedRequestProperties." +
711                "reportIntervalSeconds is non-null, then the value must be " +
712                "greater than zero.");
713    }
714
715    this.reportIntervalSeconds = reportIntervalSeconds;
716  }
717
718
719
720  /**
721   * Retrieves the log capture window object that indicates how much log content
722   * should be included in the support data archive.
723   *
724   * @return  The log capture window object that indicates how much log content
725   *          should be included in the support data archive, or {@code null}
726   *          if this should not be specified in the request and the server
727   *          should choose an appropriate amount of log content.
728   */
729  @Nullable()
730  public CollectSupportDataLogCaptureWindow getLogCaptureWindow()
731  {
732    return logCaptureWindow;
733  }
734
735
736
737  /**
738   * Specifies the log capture window object that indicates how much log content
739   * should be included in the support data archive.
740   *
741   * @param  logCaptureWindow  The log capture window object that indicates how
742   *                           much log content should be included in the
743   *                           support data archive.  It may be {@code null} to
744   *                           indicate that the server should choose an
745   *                           appropriate amount of log content.
746   */
747  public void setLogCaptureWindow(
748       @Nullable final CollectSupportDataLogCaptureWindow logCaptureWindow)
749  {
750    this.logCaptureWindow = logCaptureWindow;
751  }
752
753
754
755  /**
756   * Retrieves an additional comment that should be included in the support data
757   * archive.
758   *
759   * @return  An additional comment that should be included in the support data
760   *          archive, or {@code null} if no comment should be included.
761   */
762  @Nullable()
763  public String getComment()
764  {
765    return comment;
766  }
767
768
769
770  /**
771   * Specifies an additional comment that should be included in the support data
772   * archive.
773   *
774   * @param  comment  An additional comment that should be included in the
775   *                  support data archive.  It may be {@code null} if no
776   *                  additional comment should be included.
777   */
778  public void setComment(@Nullable final String comment)
779  {
780    this.comment = comment;
781  }
782
783
784
785  /**
786   * Retrieves the address of the backend Directory Server to which the collect
787   * support data extended request should be forwarded.
788   *
789   * @return  The address of the backend Directory Server to which the collect
790   *          support data extended request should be forwarded, or {@code null}
791   *          if the request should be processed directly by the server that
792   *          receives it.
793   */
794  @Nullable()
795  public String getProxyToServerAddress()
796  {
797    return proxyToServerAddress;
798  }
799
800
801
802  /**
803   * Retrieves the port of the backend Directory Server to which the collect
804   * support data extended request should be forwarded.
805   *
806   * @return  The port of the backend Directory Server to which the collect
807   *          support data extended request should be forwarded, or {@code null}
808   *          if the request should be processed directly by the server that
809   *          receives it.
810   */
811  @Nullable()
812  public Integer getProxyToServerPort()
813  {
814    return proxyToServerPort;
815  }
816
817
818
819  /**
820   * Specifies the address and port of the backend Directory Server to which the
821   * collect support data extended request should be forwarded.  Either both
822   * arguments must be {@code null} or both must be non-{@code null}.
823   *
824   * @param  address  The address of the backend Directory Server to which the
825   *                  request should be forwarded.  It may be {@code null} if
826   *                  the request should be processed directly by the server
827   *                  that receives it, in which case the {@code port} value
828   *                  must also be {@code null}.  If it is non-{@code null},
829   *                  then it must also be non-empty.
830   * @param  port     The port of the backend Directory Server to which the
831   *                  request should be forwarded.  It may be {@code nuoll} if
832   *                  the request should be processed directly by the server
833   *                  that receives it, in which case the {@code address} value
834   *                  must also be non-{@code null}.  If it is non-{@code null},
835   *                  then the value must be between 1 and 65535, inclusive.
836   */
837  public void setProxyToServer(@Nullable final String address,
838                               @Nullable final Integer port)
839  {
840    if (address == null)
841    {
842      Validator.ensureTrue((port == null),
843           "If CollectSupportDataExtendedRequestProperties.proxyToServer." +
844                "address is null, then " +
845                "CollectSupportDataExtendedRequestProperties.proxyToServer." +
846                "port must also be null.");
847    }
848    else
849    {
850      Validator.ensureFalse(address.isEmpty(),
851           "If CollectSupportDataExtendedRequestProperties.proxyToServer." +
852                "address is non-null, then it must also be non-empty.");
853      Validator.ensureNotNullWithMessage(port,
854           "If CollectSupportDataExtendedRequestProperties.proxyToServer." +
855                "address is non-null, then " +
856                "CollectSupportDataExtendedRequestProperties.proxyToServer." +
857                "port must also be non-null.");
858      Validator.ensureTrue(((port >= 1) && (port <= 65535)),
859           "If CollectSupportDataExtendedRequestProperties.proxyToServer." +
860                "port is non-null, then its value must be between 1 and " +
861                "65535, inclusive.");
862    }
863
864    proxyToServerAddress = address;
865    proxyToServerPort = port;
866  }
867
868
869
870  /**
871   * Retrieves the maximum size, in bytes, that may be used for a support data
872   * archive fragment returned in any single
873   * {@link CollectSupportDataArchiveFragmentIntermediateResponse} message.
874   *
875   * @return  The maximum size, in bytes, that may be used for a support data
876   *          archive fragment in any single archive fragment intermediate
877   *          response message, or {@code null} if the server should use a
878   *          default maximum fragment size.
879   */
880  @Nullable()
881  public Integer getMaximumFragmentSizeBytes()
882  {
883    return maximumFragmentSizeBytes;
884  }
885
886
887
888  /**
889   * Specifies the maximum size, in bytes, that may be used for a support data
890   * archive fragment returned in any single
891   * {@link CollectSupportDataArchiveFragmentIntermediateResponse} message.
892   *
893   * @param  maximumFragmentSizeBytes  The maximum size, in bytes, that may be
894   *                                   used for a support data archive fragment
895   *                                   returned in any single archive fragment
896   *                                   intermediate response message.  It may be
897   *                                   {@code null} if the server should use a
898   *                                   default maximum fragment size.  If it is
899   *                                   non-{@code null}, then the value must
900   *                                   also be greater than zero.
901   */
902  public void setMaximumFragmentSizeBytes(
903                   @Nullable final Integer maximumFragmentSizeBytes)
904  {
905    if (maximumFragmentSizeBytes != null)
906    {
907      Validator.ensureTrue((maximumFragmentSizeBytes > 0),
908           "If CollectSupportDataExtendedRequestProperties." +
909                "maximumFragmentSizeBytes is non-null, then its value must " +
910                "be greater than zero.");
911    }
912
913    this.maximumFragmentSizeBytes = maximumFragmentSizeBytes;
914  }
915
916
917
918  /**
919   * Retrieves a string representation of this collect support data request
920   * properties object.
921   *
922   * @return  A string representation of this collect support data request
923   *          properties object.
924   */
925  @Override()
926  @NotNull()
927  public String toString()
928  {
929    final StringBuilder buffer = new StringBuilder();
930    toString(buffer);
931    return buffer.toString();
932  }
933
934
935
936  /**
937   * Appends a string representation of this collect support data request
938   * properties object to the provided buffer.
939   *
940   * @param  buffer  The buffer to which the string representation will be
941   *                 appended.  It must not be {@code null}.
942   */
943  public void toString(@NotNull final StringBuilder buffer)
944  {
945    buffer.append("CollectSupportDataArchiveProperties(");
946    appendNameValuePair(buffer, "archiveFileName", archiveFileName);
947
948    if (encryptionPassphrase != null)
949    {
950      appendNameValuePair(buffer, "encryptionPassphrase", "*****REDACTED*****");
951    }
952
953    appendNameValuePair(buffer, "includeExpensiveData", includeExpensiveData);
954    appendNameValuePair(buffer, "includeReplicationStateDump",
955         includeReplicationStateDump);
956    appendNameValuePair(buffer, "includeBinaryFiles", includeBinaryFiles);
957    appendNameValuePair(buffer, "includeExtensionSource",
958         includeExtensionSource);
959    appendNameValuePair(buffer, "securityLevel", securityLevel);
960    appendNameValuePair(buffer, "useSequentialMode", useSequentialMode);
961    appendNameValuePair(buffer, "jstackCount", jstackCount);
962    appendNameValuePair(buffer, "reportCount", reportCount);
963    appendNameValuePair(buffer, "reportIntervalSeconds", reportIntervalSeconds);
964    appendNameValuePair(buffer, "logCaptureWindow", logCaptureWindow);
965    appendNameValuePair(buffer, "comment", comment);
966    appendNameValuePair(buffer, "proxyToServerAddress", proxyToServerAddress);
967    appendNameValuePair(buffer, "proxyToServerPort", proxyToServerPort);
968    appendNameValuePair(buffer, "maximumFragmentSizeBytes",
969         maximumFragmentSizeBytes);
970
971    buffer.append(')');
972  }
973
974
975
976  /**
977   * Appends a name-value pair to the provided buffer, if the value is
978   * non-{@code null}.
979   *
980   * @param  buffer  The buffer to which the name-value pair should be appended.
981   * @param  name    The name to be used.  It must not be {@code null}.
982   * @param  value   The value to be used.  It may be {@code null} if there is
983   *                 no value for the property.
984   */
985  private static void appendNameValuePair(@NotNull final StringBuilder buffer,
986               @NotNull final String name,
987               @Nullable final Object value)
988  {
989    if (value == null)
990    {
991      return;
992    }
993
994    if ((buffer.length() > 0) &&
995         (buffer.charAt(buffer.length() - 1) != '('))
996    {
997      buffer.append(", ");
998    }
999
1000    buffer.append(name);
1001    buffer.append('=');
1002
1003    if ((value instanceof Boolean) || (value instanceof Integer) ||
1004         (value instanceof CollectSupportDataLogCaptureWindow))
1005    {
1006      buffer.append(value);
1007    }
1008    else
1009    {
1010      buffer.append('\'');
1011      buffer.append(value);
1012      buffer.append('\'');
1013    }
1014  }
1015}