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.tasks; 037 038 039 040import java.util.ArrayList; 041import java.util.Arrays; 042import java.util.Collections; 043import java.util.Date; 044import java.util.LinkedHashMap; 045import java.util.List; 046import java.util.Map; 047import java.util.concurrent.TimeUnit; 048 049import com.unboundid.ldap.sdk.Attribute; 050import com.unboundid.ldap.sdk.Entry; 051import com.unboundid.util.Debug; 052import com.unboundid.util.NotMutable; 053import com.unboundid.util.NotNull; 054import com.unboundid.util.Nullable; 055import com.unboundid.util.StaticUtils; 056import com.unboundid.util.ThreadSafety; 057import com.unboundid.util.ThreadSafetyLevel; 058import com.unboundid.util.args.ArgumentException; 059import com.unboundid.util.args.DurationArgument; 060 061import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*; 062 063 064 065/** 066 * This class defines a Directory Server task that can be used to invoke the 067 * collect-support-data tool to capture a variety of information that may help 068 * monitor the state of the server or diagnose potential problems. 069 * <BR> 070 * <BLOCKQUOTE> 071 * <B>NOTE:</B> This class, and other classes within the 072 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 073 * supported for use against Ping Identity, UnboundID, and 074 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 075 * for proprietary functionality or for external specifications that are not 076 * considered stable or mature enough to be guaranteed to work in an 077 * interoperable way with other types of LDAP servers. 078 * </BLOCKQUOTE> 079 * <BR> 080 * The properties that are available for use with this type of task include: 081 * <UL> 082 * <LI>The path (on the server filesystem) to which the support data archive 083 * should be written. If this is not provided, then the server will 084 * determine an appropriate output file to use. If this is provided and 085 * refers to a file that exists, that file will be overwritten. If this 086 * is provided and refers to a directory that exists, then a file will 087 * be created in that directory with a server-generated name. If this 088 * is provided and refers to a file that does not exist, then its parent 089 * directory must exist, and a new file will be created with the specified 090 * path.</LI> 091 * <LI>The path (on the server filesystem) to a file containing the passphrase 092 * to use to encrypt the contents of the support data archive. If this is 093 * not provided, then the support data archive will not be encrypted.</LI> 094 * <LI>A flag that indicates whether to include data that may be expensive to 095 * capture in the support data archive. This information will not be 096 * included by default.</LI> 097 * <LI>A flag that indicates whether to include a replication state dump 098 * (which may be several megabytes in size) in the support data 099 * archive. This information will not be included by default.</LI> 100 * <LI>A flag that indicates whether to include binary files in the support 101 * data archive. Binary files will not be included by default.</LI> 102 * <LI>A flag that indicates whether to include source code (if available) to 103 * any third-party extensions installed in the server. Extension source 104 * code will not be included by default.</LI> 105 * <LI>The data security level to use when redacting data to include in the 106 * support data archive. If this is not specified, the server will 107 * select an appropriate security level.</LI> 108 * <LI>A flag that indicates whether to capture items in sequential mode 109 * (which will use less memory, but at the expense of taking longer to 110 * complete) rather than in parallel. Support data will be captured in 111 * parallel by default.</LI> 112 * <LI>The number and duration between intervals for use when collecting 113 * output of tools (like vmstat, iostat, mpstat, etc.) that use 114 * sampling over time. If this is not provided, the server will use a 115 * default count and interval.</LI> 116 * <LI>The number of times to invoke the jstack utility to obtain a stack 117 * trace of threads running in the JVM. If this is not provided, the 118 * server will use a default count.</LI> 119 * <LI>The duration (the length of time before the time the task is invoked) 120 * for log messages to be included in the support data archive. If this 121 * is not provided, the server will automatically select the amount of 122 * log content to include.</LI> 123 * <LI>The amount of data in kilobytes to capture from the beginning or end of 124 * each log file. If this is not provided, the server will automatically 125 * select the amount of log content to include.</LI> 126 * <LI>An optional comment to include in the support data archive.</LI> 127 * </UL> 128 */ 129@NotMutable() 130@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 131public final class CollectSupportDataTask 132 extends Task 133{ 134 /** 135 * The fully-qualified name of the Java class that is used for the collect 136 * support data task. 137 */ 138 @NotNull static final String COLLECT_SUPPORT_DATA_TASK_CLASS = 139 "com.unboundid.directory.server.tasks.CollectSupportDataTask"; 140 141 142 143 /** 144 * The prefix that will appear at the beginning of all attribute names used by 145 * the collect support data task. 146 */ 147 @NotNull private static final String ATTR_PREFIX = 148 "ds-task-collect-support-data-"; 149 150 151 152 /** 153 * The name of the attribute used to specify a comment to include in the 154 * support data archive. 155 */ 156 @NotNull public static final String ATTR_COMMENT = ATTR_PREFIX + "comment"; 157 158 159 160 /** 161 * The name of the attribute used to specify the path to a file containing the 162 * passphrase to use to encrypt the contents of the support data archive. 163 */ 164 @NotNull public static final String ATTR_ENCRYPTION_PASSPHRASE_FILE = 165 ATTR_PREFIX + "encryption-passphrase-file"; 166 167 168 169 /** 170 * The name of the attribute used to indicate whether the support data archive 171 * may include binary files that may otherwise have been omitted. 172 */ 173 @NotNull public static final String ATTR_INCLUDE_BINARY_FILES = 174 ATTR_PREFIX + "include-binary-files"; 175 176 177 178 /** 179 * The name of the attribute used to indicate whether the support data archive 180 * should include information that may be expensive to capture. 181 */ 182 @NotNull public static final String ATTR_INCLUDE_EXPENSIVE_DATA = 183 ATTR_PREFIX + "include-expensive-data"; 184 185 186 187 /** 188 * The name of the attribute used to indicate whether the support data archive 189 * may include the source code (if available) for any third-party extensions 190 * installed in the server. 191 */ 192 @NotNull public static final String ATTR_INCLUDE_EXTENSION_SOURCE = 193 ATTR_PREFIX + "include-extension-source"; 194 195 196 197 /** 198 * The name of the attribute used to indicate whether the support data archive 199 * should include a replication state dump (which may be several megabytes in 200 * size). 201 */ 202 @NotNull public static final String ATTR_INCLUDE_REPLICATION_STATE_DUMP = 203 ATTR_PREFIX + "include-replication-state-dump"; 204 205 206 207 /** 208 * The name of the attribute used to specify the number of times to invoke the 209 * jstack utility to capture server thread stack traces. 210 */ 211 @NotNull public static final String ATTR_JSTACK_COUNT = 212 ATTR_PREFIX + "jstack-count"; 213 214 215 216 /** 217 * The name of the attribute used to specify the length of time that should be 218 * covered by the log data included in the support data archive. 219 */ 220 @NotNull public static final String ATTR_LOG_DURATION = 221 ATTR_PREFIX + "log-duration"; 222 223 224 225 /** 226 * The name of the attribute used to specify the end time for the range of 227 * log messages that should be included in the support data archive. 228 */ 229 @NotNull public static final String ATTR_LOG_END_TIME = 230 ATTR_PREFIX + "log-end-time"; 231 232 233 234 /** 235 * The name of the attribute used to specify the start time for the range of 236 * log messages that should be included in the support data archive. 237 */ 238 @NotNull public static final String ATTR_LOG_START_TIME = 239 ATTR_PREFIX + "log-start-time"; 240 241 242 243 /** 244 * The name of the attribute used to specify the amount of data in kilobytes 245 * to capture from the beginning of each log file included in the support data 246 * archive. 247 */ 248 @NotNull public static final String ATTR_LOG_FILE_HEAD_COLLECTION_SIZE_KB = 249 ATTR_PREFIX + "log-file-head-collection-size-kb"; 250 251 252 253 /** 254 * The name of the attribute used to specify the amount of data in kilobytes 255 * to capture from the end of each log file included in the support data 256 * archive. 257 */ 258 @NotNull public static final String ATTR_LOG_FILE_TAIL_COLLECTION_SIZE_KB = 259 ATTR_PREFIX + "log-file-tail-collection-size-kb"; 260 261 262 263 /** 264 * The name of the attribute used to specify the path to which the support 265 * data archive should be written. 266 */ 267 @NotNull public static final String ATTR_OUTPUT_PATH = 268 ATTR_PREFIX + "output-path"; 269 270 271 272 /** 273 * The name of the attribute used to specify the number of intervals to 274 * capture for tools that capture multiple samples. 275 */ 276 @NotNull public static final String ATTR_REPORT_COUNT = 277 ATTR_PREFIX + "report-count"; 278 279 280 281 /** 282 * The name of the attribute used to specify the length of time, in seconds, 283 * between samples collected from tools that capture multiple samples. 284 */ 285 @NotNull public static final String ATTR_REPORT_INTERVAL_SECONDS = 286 ATTR_PREFIX + "report-interval-seconds"; 287 288 289 290 /** 291 *The name of the attribute used to specify the minimum age of previous 292 * support data archives that should be retained. 293 */ 294 @NotNull public static final String ATTR_RETAIN_PREVIOUS_ARCHIVE_AGE = 295 ATTR_PREFIX + "retain-previous-support-data-archive-age"; 296 297 298 299 /** 300 *The name of the attribute used to specify the minimum number of previous 301 * support data archives that should be retained. 302 */ 303 @NotNull public static final String ATTR_RETAIN_PREVIOUS_ARCHIVE_COUNT = 304 ATTR_PREFIX + "retain-previous-support-data-archive-count"; 305 306 307 308 /** 309 * The name of the attribute used to specify the security level to use for 310 * information added to the support data archive. 311 */ 312 @NotNull public static final String ATTR_SECURITY_LEVEL = 313 ATTR_PREFIX + "security-level"; 314 315 316 317 /** 318 * The name of the attribute used to indicate whether to collect items 319 * sequentially rather than in parallel. 320 */ 321 @NotNull public static final String ATTR_USE_SEQUENTIAL_MODE = 322 ATTR_PREFIX + "use-sequential-mode"; 323 324 325 326 /** 327 * The name of the object class used in collect support data task entries. 328 */ 329 @NotNull public static final String OC_COLLECT_SUPPORT_DATA_TASK = 330 "ds-task-collect-support-data"; 331 332 333 334 /** 335 * The task property that will be used for the comment. 336 */ 337 @NotNull static final TaskProperty PROPERTY_COMMENT = 338 new TaskProperty(ATTR_COMMENT, INFO_CSD_DISPLAY_NAME_COMMENT.get(), 339 INFO_CSD_DESCRIPTION_COMMENT.get(), String.class, false, false, 340 false); 341 342 343 344 /** 345 * The task property that will be used for the encryption passphrase file. 346 */ 347 @NotNull static final TaskProperty PROPERTY_ENCRYPTION_PASSPHRASE_FILE = 348 new TaskProperty(ATTR_ENCRYPTION_PASSPHRASE_FILE, 349 INFO_CSD_DISPLAY_NAME_ENC_PW_FILE.get(), 350 INFO_CSD_DESCRIPTION_ENC_PW_FILE.get(), String.class, false, false, 351 false); 352 353 354 355 /** 356 * The task property that will be used for the include binary files flag. 357 */ 358 @NotNull static final TaskProperty PROPERTY_INCLUDE_BINARY_FILES = 359 new TaskProperty(ATTR_INCLUDE_BINARY_FILES, 360 INFO_CSD_DISPLAY_NAME_INCLUDE_BINARY_FILES.get(), 361 INFO_CSD_DESCRIPTION_INCLUDE_BINARY_FILES.get(), Boolean.class, false, 362 false, false); 363 364 365 366 /** 367 * The task property that will be used for the include expensive data flag. 368 */ 369 @NotNull static final TaskProperty PROPERTY_INCLUDE_EXPENSIVE_DATA = 370 new TaskProperty(ATTR_INCLUDE_EXPENSIVE_DATA, 371 INFO_CSD_DISPLAY_NAME_INCLUDE_EXPENSIVE_DATA.get(), 372 INFO_CSD_DESCRIPTION_INCLUDE_EXPENSIVE_DATA.get(), Boolean.class, 373 false, false, false); 374 375 376 377 /** 378 * The task property that will be used for the include extension source flag. 379 */ 380 @NotNull static final TaskProperty PROPERTY_INCLUDE_EXTENSION_SOURCE = 381 new TaskProperty(ATTR_INCLUDE_EXTENSION_SOURCE, 382 INFO_CSD_DISPLAY_NAME_INCLUDE_EXTENSION_SOURCE.get(), 383 INFO_CSD_DESCRIPTION_INCLUDE_EXTENSION_SOURCE.get(), Boolean.class, 384 false, false, false); 385 386 387 388 /** 389 * The task property that will be used for the include replication state dump 390 * flag. 391 */ 392 @NotNull static final TaskProperty PROPERTY_INCLUDE_REPLICATION_STATE_DUMP = 393 new TaskProperty(ATTR_INCLUDE_REPLICATION_STATE_DUMP, 394 INFO_CSD_DISPLAY_NAME_INCLUDE_REPLICATION_STATE_DUMP.get(), 395 INFO_CSD_DESCRIPTION_INCLUDE_REPLICATION_STATE_DUMP.get(), 396 Boolean.class, false, false, false); 397 398 399 400 /** 401 * The task property that will be used for the jstack count. 402 */ 403 @NotNull static final TaskProperty PROPERTY_JSTACK_COUNT = 404 new TaskProperty(ATTR_JSTACK_COUNT, 405 INFO_CSD_DISPLAY_NAME_JSTACK_COUNT.get(), 406 INFO_CSD_DESCRIPTION_JSTACK_COUNT.get(), 407 Long.class, false, false, false); 408 409 410 411 /** 412 * The task property that will be used for the log duration. 413 */ 414 @NotNull static final TaskProperty PROPERTY_LOG_DURATION = 415 new TaskProperty(ATTR_LOG_DURATION, 416 INFO_CSD_DISPLAY_NAME_LOG_DURATION.get(), 417 INFO_CSD_DESCRIPTION_LOG_DURATION.get(), 418 String.class, false, false, false); 419 420 421 422 /** 423 * The task property that will be used for the log end time. 424 */ 425 @NotNull static final TaskProperty PROPERTY_LOG_END_TIME = 426 new TaskProperty(ATTR_LOG_END_TIME, 427 INFO_CSD_DISPLAY_NAME_LOG_END_TIME.get(), 428 INFO_CSD_DESCRIPTION_LOG_END_TIME.get(), 429 Date.class, false, false, false); 430 431 432 433 /** 434 * The task property that will be used for the log start time. 435 */ 436 @NotNull static final TaskProperty PROPERTY_LOG_START_TIME = 437 new TaskProperty(ATTR_LOG_START_TIME, 438 INFO_CSD_DISPLAY_NAME_LOG_START_TIME.get(), 439 INFO_CSD_DESCRIPTION_LOG_START_TIME.get(), 440 Date.class, false, false, false); 441 442 443 444 /** 445 * The task property that will be used for the log head size. 446 */ 447 @NotNull static final TaskProperty PROPERTY_LOG_FILE_HEAD_COLLECTION_SIZE_KB = 448 new TaskProperty(ATTR_LOG_FILE_HEAD_COLLECTION_SIZE_KB, 449 INFO_CSD_DISPLAY_NAME_LOG_HEAD_SIZE_KB.get(), 450 INFO_CSD_DESCRIPTION_LOG_HEAD_SIZE_KB.get(), 451 Long.class, false, false, false); 452 453 454 455 /** 456 * The task property that will be used for the log tail size. 457 */ 458 @NotNull static final TaskProperty PROPERTY_LOG_FILE_TAIL_COLLECTION_SIZE_KB = 459 new TaskProperty(ATTR_LOG_FILE_TAIL_COLLECTION_SIZE_KB, 460 INFO_CSD_DISPLAY_NAME_LOG_TAIL_SIZE_KB.get(), 461 INFO_CSD_DESCRIPTION_LOG_TAIL_SIZE_KB.get(), 462 Long.class, false, false, false); 463 464 465 466 /** 467 * The task property that will be used for the output path. 468 */ 469 @NotNull static final TaskProperty PROPERTY_OUTPUT_PATH = 470 new TaskProperty(ATTR_OUTPUT_PATH, 471 INFO_CSD_DISPLAY_NAME_OUTPUT_PATH.get(), 472 INFO_CSD_DESCRIPTION_OUTPUT_PATH.get(), 473 String.class, false, false, false); 474 475 476 477 /** 478 * The task property that will be used for the report count. 479 */ 480 @NotNull static final TaskProperty PROPERTY_REPORT_COUNT = 481 new TaskProperty(ATTR_REPORT_COUNT, 482 INFO_CSD_DISPLAY_NAME_REPORT_COUNT.get(), 483 INFO_CSD_DESCRIPTION_REPORT_COUNT.get(), 484 Long.class, false, false, false); 485 486 487 488 /** 489 * The task property that will be used for the report interval. 490 */ 491 @NotNull static final TaskProperty PROPERTY_REPORT_INTERVAL_SECONDS = 492 new TaskProperty(ATTR_REPORT_INTERVAL_SECONDS, 493 INFO_CSD_DISPLAY_NAME_REPORT_INTERVAL.get(), 494 INFO_CSD_DESCRIPTION_REPORT_INTERVAL.get(), 495 Long.class, false, false, false); 496 497 498 499 /** 500 * The task property that will be used for the retain previous support data 501 * archive age. 502 */ 503 @NotNull static final TaskProperty PROPERTY_RETAIN_PREVIOUS_ARCHIVE_AGE = 504 new TaskProperty(ATTR_RETAIN_PREVIOUS_ARCHIVE_AGE, 505 INFO_CSD_DISPLAY_NAME_RETAIN_PREVIOUS_ARCHIVE_AGE.get(), 506 INFO_CSD_DESCRIPTION_RETAIN_PREVIOUS_ARCHIVE_AGE.get(), 507 String.class, false, false, false); 508 509 510 511 /** 512 * The task property that will be used for the retain previous support data 513 * archive count. 514 */ 515 @NotNull static final TaskProperty PROPERTY_RETAIN_PREVIOUS_ARCHIVE_COUNT = 516 new TaskProperty(ATTR_RETAIN_PREVIOUS_ARCHIVE_COUNT, 517 INFO_CSD_DISPLAY_NAME_RETAIN_PREVIOUS_ARCHIVE_COUNT.get(), 518 INFO_CSD_DESCRIPTION_RETAIN_PREVIOUS_ARCHIVE_COUNT.get(), 519 Long.class, false, false, false); 520 521 522 523 /** 524 * The task property that will be used for the security level. 525 */ 526 @NotNull static final TaskProperty PROPERTY_SECURITY_LEVEL = 527 new TaskProperty(ATTR_SECURITY_LEVEL, 528 INFO_CSD_DISPLAY_NAME_SECURITY_LEVEL.get(), 529 INFO_CSD_DESCRIPTION_SECURITY_LEVEL.get( 530 CollectSupportDataSecurityLevel.NONE.getName(), 531 CollectSupportDataSecurityLevel.OBSCURE_SECRETS.getName(), 532 CollectSupportDataSecurityLevel.MAXIMUM.getName()), 533 String.class, false, false, false, 534 new Object[] 535 { 536 CollectSupportDataSecurityLevel.NONE.getName(), 537 CollectSupportDataSecurityLevel.OBSCURE_SECRETS.getName(), 538 CollectSupportDataSecurityLevel.MAXIMUM.getName() 539 }); 540 541 542 543 /** 544 * The task property that will be used for the use sequential mode flag. 545 */ 546 @NotNull static final TaskProperty PROPERTY_USE_SEQUENTIAL_MODE = 547 new TaskProperty(ATTR_USE_SEQUENTIAL_MODE, 548 INFO_CSD_DISPLAY_NAME_USE_SEQUENTIAL_MODE.get(), 549 INFO_CSD_DESCRIPTION_USE_SEQUENTIAL_MODE.get(), 550 Boolean.class, false, false, false); 551 552 553 554 /** 555 * The serial version UID for this serializable class. 556 */ 557 private static final long serialVersionUID = -3414981969721886291L; 558 559 560 561 // Indicates whether to include binary files in the support data archive. 562 @Nullable private final Boolean includeBinaryFiles; 563 564 // Indicates whether to include expensive data in the support data archive. 565 @Nullable private final Boolean includeExpensiveData; 566 567 // Indicates whether to include third-party extension source code in the 568 // support data archive. 569 @Nullable private final Boolean includeExtensionSource; 570 571 // Indicates whether to include a replication state dump in the support data 572 // archive. 573 @Nullable private final Boolean includeReplicationStateDump; 574 575 // Indicates whether to capture information sequentially rather than in 576 // parallel. 577 @Nullable private final Boolean useSequentialMode; 578 579 // The security level to use for data included in the support data archive. 580 @Nullable private final CollectSupportDataSecurityLevel securityLevel; 581 582 // The time at which to end collecting log data. 583 @Nullable private final Date logEndTime; 584 585 // The time at which to start collecting log data. 586 @Nullable private final Date logStartTime; 587 588 // The number of jstacks to include in the support data archive. 589 @Nullable private final Integer jstackCount; 590 591 // The amount of data in kilobytes to capture from the beginning of each log 592 // file. 593 @Nullable private final Integer logFileHeadCollectionSizeKB; 594 595 // The amount of data in kilobytes to capture from the end of each log file. 596 @Nullable private final Integer logFileTailCollectionSizeKB; 597 598 // The report count to use for sampled metrics. 599 @Nullable private final Integer reportCount; 600 601 // The report interval, in seconds, to use for sampled metrics. 602 @Nullable private final Integer reportIntervalSeconds; 603 604 // The minimum number of existing support data archives that should be 605 // retained. 606 @Nullable private final Integer retainPreviousSupportDataArchiveCount; 607 608 // A comment to include in the support data archive. 609 @Nullable private final String comment; 610 611 // The path to the encryption passphrase file. 612 @Nullable private final String encryptionPassphraseFile; 613 614 // A string representation of the log duration to capture. 615 @Nullable private final String logDuration; 616 617 // The path to which the support data archive should be written. 618 @Nullable private final String outputPath; 619 620 // The minimum age for existing support data archives that should be retained. 621 @Nullable private final String retainPreviousSupportDataArchiveAge; 622 623 624 625 /** 626 * Creates a new collect support data task instance that will use default 627 * settings for all properties. This instance may be used to invoke the 628 * task, but it can also be used for obtaining general information about this 629 * task, including the task name, description, and supported properties. 630 */ 631 public CollectSupportDataTask() 632 { 633 this(new CollectSupportDataTaskProperties()); 634 } 635 636 637 638 /** 639 * Creates a new collect support data task instance using the provided 640 * properties. 641 * 642 * @param properties The properties to use to create the collect support 643 * data task. It must not be {@code null}. 644 */ 645 public CollectSupportDataTask( 646 @NotNull final CollectSupportDataTaskProperties properties) 647 { 648 super(properties.getTaskID(), COLLECT_SUPPORT_DATA_TASK_CLASS, 649 properties.getScheduledStartTime(), properties.getDependencyIDs(), 650 properties.getFailedDependencyAction(), properties.getNotifyOnStart(), 651 properties.getNotifyOnCompletion(), properties.getNotifyOnSuccess(), 652 properties.getNotifyOnError(), properties.getAlertOnStart(), 653 properties.getAlertOnSuccess(), properties.getAlertOnError()); 654 655 includeBinaryFiles = properties.getIncludeBinaryFiles(); 656 includeExpensiveData = properties.getIncludeExpensiveData(); 657 includeExtensionSource = properties.getIncludeExtensionSource(); 658 includeReplicationStateDump = properties.getIncludeReplicationStateDump(); 659 useSequentialMode = properties.getUseSequentialMode(); 660 securityLevel = properties.getSecurityLevel(); 661 jstackCount = properties.getJStackCount(); 662 logFileHeadCollectionSizeKB = properties.getLogFileHeadCollectionSizeKB(); 663 logFileTailCollectionSizeKB = properties.getLogFileTailCollectionSizeKB(); 664 reportCount = properties.getReportCount(); 665 reportIntervalSeconds = properties.getReportIntervalSeconds(); 666 retainPreviousSupportDataArchiveCount = 667 properties.getRetainPreviousSupportDataArchiveCount(); 668 comment = properties.getComment(); 669 encryptionPassphraseFile = properties.getEncryptionPassphraseFile(); 670 logStartTime = properties.getLogStartTime(); 671 logEndTime = properties.getLogEndTime(); 672 logDuration = properties.getLogDuration(); 673 outputPath = properties.getOutputPath(); 674 retainPreviousSupportDataArchiveAge = 675 properties.getRetainPreviousSupportDataArchiveAge(); 676 } 677 678 679 680 /** 681 * Creates a new collect support data task from the provided entry. 682 * 683 * @param entry The entry to use to create this collect support data task. 684 * 685 * @throws TaskException If the provided entry cannot be parsed as a collect 686 * support data task entry. 687 */ 688 public CollectSupportDataTask(@NotNull final Entry entry) 689 throws TaskException 690 { 691 super(entry); 692 693 includeBinaryFiles = 694 entry.getAttributeValueAsBoolean(ATTR_INCLUDE_BINARY_FILES); 695 includeExpensiveData = 696 entry.getAttributeValueAsBoolean(ATTR_INCLUDE_EXPENSIVE_DATA); 697 includeExtensionSource = 698 entry.getAttributeValueAsBoolean(ATTR_INCLUDE_EXTENSION_SOURCE); 699 includeReplicationStateDump = 700 entry.getAttributeValueAsBoolean(ATTR_INCLUDE_REPLICATION_STATE_DUMP); 701 useSequentialMode = 702 entry.getAttributeValueAsBoolean(ATTR_USE_SEQUENTIAL_MODE); 703 704 jstackCount = entry.getAttributeValueAsInteger(ATTR_JSTACK_COUNT); 705 logFileHeadCollectionSizeKB = entry.getAttributeValueAsInteger( 706 ATTR_LOG_FILE_HEAD_COLLECTION_SIZE_KB); 707 logFileTailCollectionSizeKB = entry.getAttributeValueAsInteger( 708 ATTR_LOG_FILE_TAIL_COLLECTION_SIZE_KB); 709 reportCount = entry.getAttributeValueAsInteger(ATTR_REPORT_COUNT); 710 reportIntervalSeconds = 711 entry.getAttributeValueAsInteger(ATTR_REPORT_INTERVAL_SECONDS); 712 retainPreviousSupportDataArchiveCount = 713 entry.getAttributeValueAsInteger(ATTR_RETAIN_PREVIOUS_ARCHIVE_COUNT); 714 715 comment = entry.getAttributeValue(ATTR_COMMENT); 716 encryptionPassphraseFile = 717 entry.getAttributeValue(ATTR_ENCRYPTION_PASSPHRASE_FILE); 718 outputPath = entry.getAttributeValue(ATTR_OUTPUT_PATH); 719 720 final String securityLevelStr = 721 entry.getAttributeValue(ATTR_SECURITY_LEVEL); 722 if (securityLevelStr == null) 723 { 724 securityLevel = null; 725 } 726 else 727 { 728 securityLevel = CollectSupportDataSecurityLevel.forName(securityLevelStr); 729 if (securityLevel == null) 730 { 731 throw new TaskException(ERR_CSD_ENTRY_INVALID_SECURITY_LEVEL.get( 732 entry.getDN(), securityLevelStr, ATTR_SECURITY_LEVEL, 733 CollectSupportDataSecurityLevel.NONE.getName(), 734 CollectSupportDataSecurityLevel.OBSCURE_SECRETS.getName(), 735 CollectSupportDataSecurityLevel.MAXIMUM.getName())); 736 } 737 } 738 739 if (entry.hasAttribute(ATTR_LOG_START_TIME)) 740 { 741 logStartTime = entry.getAttributeValueAsDate(ATTR_LOG_START_TIME); 742 if (logStartTime == null) 743 { 744 throw new TaskException( 745 ERR_CSD_ENTRY_INVALID_TIMESTAMP.get(entry.getDN(), 746 entry.getAttributeValue(ATTR_LOG_START_TIME), 747 ATTR_LOG_START_TIME)); 748 } 749 } 750 else 751 { 752 logStartTime = null; 753 } 754 755 if (entry.hasAttribute(ATTR_LOG_END_TIME)) 756 { 757 logEndTime = entry.getAttributeValueAsDate(ATTR_LOG_END_TIME); 758 if (logEndTime == null) 759 { 760 throw new TaskException( 761 ERR_CSD_ENTRY_INVALID_TIMESTAMP.get(entry.getDN(), 762 entry.getAttributeValue(ATTR_LOG_END_TIME), 763 ATTR_LOG_END_TIME)); 764 } 765 } 766 else 767 { 768 logEndTime = null; 769 } 770 771 logDuration = entry.getAttributeValue(ATTR_LOG_DURATION); 772 if (logDuration != null) 773 { 774 try 775 { 776 DurationArgument.parseDuration(logDuration, TimeUnit.MILLISECONDS); 777 } 778 catch (final Exception e) 779 { 780 Debug.debugException(e); 781 throw new TaskException( 782 ERR_CSD_ENTRY_INVALID_DURATION.get(entry.getDN(), logDuration, 783 ATTR_LOG_DURATION), 784 e); 785 } 786 } 787 788 retainPreviousSupportDataArchiveAge = 789 entry.getAttributeValue(ATTR_RETAIN_PREVIOUS_ARCHIVE_AGE); 790 if (retainPreviousSupportDataArchiveAge != null) 791 { 792 try 793 { 794 DurationArgument.parseDuration(retainPreviousSupportDataArchiveAge, 795 TimeUnit.MILLISECONDS); 796 } 797 catch (final Exception e) 798 { 799 Debug.debugException(e); 800 throw new TaskException( 801 ERR_CSD_ENTRY_INVALID_DURATION.get(entry.getDN(), 802 retainPreviousSupportDataArchiveAge, 803 ATTR_RETAIN_PREVIOUS_ARCHIVE_AGE), 804 e); 805 } 806 } 807 } 808 809 810 811 /** 812 * Creates a new collect support data task from the provided set of task 813 * properties. 814 * 815 * @param properties The set of task properties and their corresponding 816 * values to use for the task. It must not be 817 * {@code null}. 818 * 819 * @throws TaskException If the provided set of properties cannot be used to 820 * create a valid collect support data task. 821 */ 822 public CollectSupportDataTask( 823 @NotNull final Map<TaskProperty,List<Object>> properties) 824 throws TaskException 825 { 826 super(COLLECT_SUPPORT_DATA_TASK_CLASS, properties); 827 828 Boolean includeBinary = null; 829 Boolean includeExpensive = null; 830 Boolean includeReplicationState = null; 831 Boolean includeSource = null; 832 Boolean sequentialMode = null; 833 CollectSupportDataSecurityLevel secLevel = null; 834 Date logEndDate = null; 835 Date logStartDate = null; 836 Integer logHeadSizeKB = null; 837 Integer logTailSizeKB = null; 838 Integer numJStacks = null; 839 Integer numReports = null; 840 Integer reportIntervalSecs = null; 841 Integer retainCount = null; 842 String commentStr = null; 843 String encPWFile = null; 844 String logDurationStr = null; 845 String outputPathStr = null; 846 String retainAge = null; 847 848 for (final Map.Entry<TaskProperty,List<Object>> entry : 849 properties.entrySet()) 850 { 851 final TaskProperty p = entry.getKey(); 852 final String attrName = StaticUtils.toLowerCase(p.getAttributeName()); 853 final List<Object> values = entry.getValue(); 854 855 if (attrName.equals(ATTR_INCLUDE_BINARY_FILES)) 856 { 857 includeBinary = parseBoolean(p, values, includeBinary); 858 } 859 else if (attrName.equals(ATTR_INCLUDE_EXPENSIVE_DATA)) 860 { 861 includeExpensive = parseBoolean(p, values, includeExpensive); 862 } 863 else if (attrName.equals(ATTR_INCLUDE_REPLICATION_STATE_DUMP)) 864 { 865 includeReplicationState = 866 parseBoolean(p, values, includeReplicationState); 867 } 868 else if (attrName.equals(ATTR_INCLUDE_EXTENSION_SOURCE)) 869 { 870 includeSource = parseBoolean(p, values, includeSource); 871 } 872 else if (attrName.equals(ATTR_USE_SEQUENTIAL_MODE)) 873 { 874 sequentialMode = parseBoolean(p, values, sequentialMode); 875 } 876 else if (attrName.equals(ATTR_SECURITY_LEVEL)) 877 { 878 final String secLevelStr = parseString(p, values, 879 getSecurityLevelName(secLevel)); 880 secLevel = CollectSupportDataSecurityLevel.forName(secLevelStr); 881 } 882 else if (attrName.equals(ATTR_JSTACK_COUNT)) 883 { 884 numJStacks = parseLong(p, values, 885 getIntegerAsLong(numJStacks)).intValue(); 886 } 887 else if (attrName.equals(ATTR_LOG_FILE_HEAD_COLLECTION_SIZE_KB)) 888 { 889 logHeadSizeKB = parseLong(p, values, 890 getIntegerAsLong(logHeadSizeKB)).intValue(); 891 } 892 else if (attrName.equals(ATTR_LOG_FILE_TAIL_COLLECTION_SIZE_KB)) 893 { 894 logTailSizeKB = parseLong(p, values, 895 getIntegerAsLong(logTailSizeKB)).intValue(); 896 } 897 else if (attrName.equals(ATTR_REPORT_COUNT)) 898 { 899 numReports = parseLong(p, values, 900 getIntegerAsLong(numReports)).intValue(); 901 } 902 else if (attrName.equals(ATTR_REPORT_INTERVAL_SECONDS)) 903 { 904 reportIntervalSecs = parseLong(p, values, 905 getIntegerAsLong(reportIntervalSecs)).intValue(); 906 } 907 else if (attrName.equals(ATTR_COMMENT)) 908 { 909 commentStr = parseString(p, values, commentStr); 910 } 911 else if (attrName.equals(ATTR_ENCRYPTION_PASSPHRASE_FILE)) 912 { 913 encPWFile = parseString(p, values, encPWFile); 914 } 915 else if (attrName.equals(ATTR_LOG_START_TIME)) 916 { 917 logStartDate = parseDate(p, values, null); 918 } 919 else if (attrName.equals(ATTR_LOG_END_TIME)) 920 { 921 logEndDate = parseDate(p, values, null); 922 } 923 else if (attrName.equals(ATTR_LOG_DURATION)) 924 { 925 logDurationStr = parseString(p, values, logDurationStr); 926 try 927 { 928 DurationArgument.parseDuration(logDurationStr, TimeUnit.MILLISECONDS); 929 } 930 catch (final Exception e) 931 { 932 Debug.debugException(e); 933 throw new TaskException( 934 ERR_CSD_PROPERTY_INVALID_DURATION.get(logDurationStr, 935 ATTR_LOG_DURATION), 936 e); 937 } 938 } 939 else if (attrName.equals(ATTR_OUTPUT_PATH)) 940 { 941 outputPathStr = parseString(p, values, outputPathStr); 942 } 943 else if (attrName.equals(ATTR_RETAIN_PREVIOUS_ARCHIVE_COUNT)) 944 { 945 retainCount = parseLong(p, values, 946 getIntegerAsLong(retainCount)).intValue(); 947 } 948 else if (attrName.equals(ATTR_RETAIN_PREVIOUS_ARCHIVE_AGE)) 949 { 950 retainAge = parseString(p, values, retainAge); 951 try 952 { 953 DurationArgument.parseDuration(retainAge, TimeUnit.MILLISECONDS); 954 } 955 catch (final Exception e) 956 { 957 Debug.debugException(e); 958 throw new TaskException( 959 ERR_CSD_PROPERTY_INVALID_DURATION.get(retainAge, 960 ATTR_RETAIN_PREVIOUS_ARCHIVE_AGE), 961 e); 962 } 963 } 964 } 965 966 includeBinaryFiles = includeBinary; 967 includeExpensiveData = includeExpensive; 968 includeReplicationStateDump = includeReplicationState; 969 includeExtensionSource = includeSource; 970 useSequentialMode = sequentialMode; 971 securityLevel = secLevel; 972 jstackCount = numJStacks; 973 logFileHeadCollectionSizeKB = logHeadSizeKB; 974 logFileTailCollectionSizeKB = logTailSizeKB; 975 reportCount = numReports; 976 reportIntervalSeconds = reportIntervalSecs; 977 retainPreviousSupportDataArchiveCount = retainCount; 978 comment = commentStr; 979 encryptionPassphraseFile = encPWFile; 980 logStartTime = logStartDate; 981 logEndTime = logEndDate; 982 logDuration = logDurationStr; 983 outputPath = outputPathStr; 984 retainPreviousSupportDataArchiveAge = retainAge; 985 } 986 987 988 989 /** 990 * Retrieves the name of the provided security level. 991 * 992 * @param securityLevel The security level for which to retrieve the name. 993 * It may be {@code null}. 994 * 995 * @return The name of the provided security level, or {@code null} if the 996 * provided security level is {@code null}. 997 */ 998 @Nullable() 999 static String getSecurityLevelName( 1000 @Nullable final CollectSupportDataSecurityLevel securityLevel) 1001 { 1002 if (securityLevel == null) 1003 { 1004 return null; 1005 } 1006 else 1007 { 1008 return securityLevel.getName(); 1009 } 1010 } 1011 1012 1013 1014 /** 1015 * Retrieves the value of the provided {@code Integer} object as a 1016 * {@code Long}. 1017 * 1018 * @param i The {@code Integer} value to convert to a {@code Long}. It may 1019 * be {@code null}. 1020 * 1021 * @return The value of the provided {@code Integer} object as a 1022 * {@code Long}, or {@code null} if the provided value was 1023 * {@code null}. 1024 */ 1025 @Nullable() 1026 static Long getIntegerAsLong(@Nullable final Integer i) 1027 { 1028 if (i == null) 1029 { 1030 return null; 1031 } 1032 else 1033 { 1034 return i.longValue(); 1035 } 1036 } 1037 1038 1039 1040 /** 1041 * {@inheritDoc} 1042 */ 1043 @Override() 1044 @NotNull() 1045 public String getTaskName() 1046 { 1047 return INFO_CSD_TASK_NAME.get(); 1048 } 1049 1050 1051 1052 /** 1053 * {@inheritDoc} 1054 */ 1055 @Override() 1056 @NotNull() 1057 public String getTaskDescription() 1058 { 1059 return INFO_CSD_TASK_DESCRIPTION.get(); 1060 } 1061 1062 1063 1064 /** 1065 * Retrieves the path on the server filesystem to which the support data 1066 * archive should be written. 1067 * 1068 * @return The path on the server filesystem to which the support data 1069 * archive should be written, or {@code null} if no value has been 1070 * specified for the property. 1071 */ 1072 @Nullable() 1073 public String getOutputPath() 1074 { 1075 return outputPath; 1076 } 1077 1078 1079 1080 /** 1081 * Retrieves the path on the server filesystem to a file that contains the 1082 * passphrase to use to encrypt the support data archive. 1083 * 1084 * @return The path on the server filesystem to a file that contains the 1085 * passphrase to use to encrypt the support data archive, or 1086 * {@code null} if no value has been specified for the property, and 1087 * the support data archive should not be encrypted. 1088 */ 1089 @Nullable() 1090 public String getEncryptionPassphraseFile() 1091 { 1092 return encryptionPassphraseFile; 1093 } 1094 1095 1096 1097 /** 1098 * Retrieves the value of a flag that indicates whether the support data 1099 * archive may include data that is potentially expensive to collect and 1100 * could affect the performance or responsiveness of the server. 1101 * 1102 * @return The value of a flag that indicates whether the support data 1103 * archive may include data that is potentially expensive to collect, 1104 * or {@code null} if the property should not be specified when the 1105 * task is created (in which case the server will use a default 1106 * behavior of excluding expensive data). 1107 */ 1108 @Nullable() 1109 public Boolean getIncludeExpensiveData() 1110 { 1111 return includeExpensiveData; 1112 } 1113 1114 1115 1116 /** 1117 * Retrieves the value of a flag that indicates whether the support data 1118 * archive may include a replication state dump, which may be several 1119 * megabytes in size. 1120 * 1121 * @return The value of a flag that indicates whether the support data 1122 * archive may include a replication state dump, or {@code null} if 1123 * the property should not be specified when the task is created (in 1124 * which case the server will use a default behavior of excluding the 1125 * state dump). 1126 */ 1127 @Nullable() 1128 public Boolean getIncludeReplicationStateDump() 1129 { 1130 return includeReplicationStateDump; 1131 } 1132 1133 1134 1135 /** 1136 * Retrieves the value of a flag that indicates whether the support data 1137 * archive may include binary files. 1138 * 1139 * @return The value of a flag that indicates whether the support data 1140 * archive may include binary files, or {@code null} if the property 1141 * should not be specified when the task is created (in which case 1142 * the server will use a default behavior of excluding binary files). 1143 */ 1144 @Nullable() 1145 public Boolean getIncludeBinaryFiles() 1146 { 1147 return includeBinaryFiles; 1148 } 1149 1150 1151 1152 /** 1153 * Retrieves the value of a flag that indicates whether the support data 1154 * archive should include source code (if available) for any third-party 1155 * extensions installed in the server. 1156 * 1157 * @return The value of a flag that indicates whether the support data 1158 * archive should include source code (if available) for any 1159 * third-party extensions installed in the server, or {@code null} if 1160 * the property should not be specified when the task is created (in 1161 * which case the server will use a default behavior of excluding 1162 * extension source code). 1163 */ 1164 @Nullable() 1165 public Boolean getIncludeExtensionSource() 1166 { 1167 return includeExtensionSource; 1168 } 1169 1170 1171 1172 /** 1173 * Retrieves the value of a flag that indicates whether the server should 1174 * collect items for the support data archive in sequential mode rather than 1175 * in parallel. Collecting data in sequential mode may reduce the amount of 1176 * memory consumed during the collection process, but it will take longer to 1177 * complete. 1178 * 1179 * @return The value of a flag that indicates whether the server should 1180 * collect items for the support data archive in sequential mode 1181 * rather than in parallel, or {@code null} if the property should 1182 * not be specified when the task is created (in which case the 1183 * server will default to capturing data in parallel). 1184 */ 1185 @Nullable() 1186 public Boolean getUseSequentialMode() 1187 { 1188 return useSequentialMode; 1189 } 1190 1191 1192 1193 /** 1194 * Retrieves the security level that should be used to indicate which data 1195 * should be obscured, redacted, or omitted from the support data archive. 1196 * 1197 * @return The security level that should be used when creating the support 1198 * data archive, or {@code null} if the property should not be 1199 * specified when the task is created (in which case the server will 1200 * use a default security level). 1201 */ 1202 @Nullable() 1203 public CollectSupportDataSecurityLevel getSecurityLevel() 1204 { 1205 return securityLevel; 1206 } 1207 1208 1209 1210 /** 1211 * Retrieves the number of intervals that should be captured from tools that 1212 * use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.). 1213 * 1214 * @return The number of intervals that should be captured from tools that 1215 * use interval-based sampling, or {@code null} if the property 1216 * should not be specified when the task is created (in which case 1217 * the server will use a default report count). 1218 */ 1219 @Nullable() 1220 public Integer getReportCount() 1221 { 1222 return reportCount; 1223 } 1224 1225 1226 1227 /** 1228 * Retrieves the interval duration in seconds that should be used for tools 1229 * that use interval-based sampling (e.g., vmstat, iostat, mpstat, etc.). 1230 * 1231 * @return The interval duration in seconds that should be used for tools 1232 * that use interval-based sampling, or {@code null} if the property 1233 * should not be specified when the task is created (in which case 1234 * the server will use a default report interval). 1235 */ 1236 @Nullable() 1237 public Integer getReportIntervalSeconds() 1238 { 1239 return reportIntervalSeconds; 1240 } 1241 1242 1243 1244 /** 1245 * Retrieves the number of times that the jstack utility should be invoked to 1246 * obtain stack traces from all threads in the server. 1247 * 1248 * @return The number of times that the jstack utility should be invoked to 1249 * obtain stack traces from all threads in the server, or 1250 * {@code null} if the property should not be specified when the task 1251 * is created (in which case the server will use a default count). 1252 */ 1253 @Nullable() 1254 public Integer getJStackCount() 1255 { 1256 return jstackCount; 1257 } 1258 1259 1260 1261 /** 1262 * Retrieves the start time for the range of log messages to include in the 1263 * support data archive. 1264 * 1265 * @return The start time for the range of log messages to include in the 1266 * support data archive, or {@code null} if no log start time has 1267 * been specified. 1268 */ 1269 @Nullable() 1270 public Date getLogStartTime() 1271 { 1272 return logStartTime; 1273 } 1274 1275 1276 1277 /** 1278 * Retrieves the end time for the range of log messages to include in the 1279 * support data archive. 1280 * 1281 * @return The end time for the range of log messages to include in the 1282 * support data archive, or {@code null} if no log end time has 1283 * been specified. 1284 */ 1285 @Nullable() 1286 public Date getLogEndTime() 1287 { 1288 return logEndTime; 1289 } 1290 1291 1292 1293 /** 1294 * Retrieves a string representation of the duration (up until the time that 1295 * the collect support data task is invoked) of log content that should be 1296 * included in the support data archive. 1297 * 1298 * @return A string representation of the duration of log content that should 1299 * be included in the support data archive, or {@code null} if the 1300 * property should not be specified when the task is created (in 1301 * which case the server will use a default behavior for selecting 1302 * the amount of log content to include). 1303 */ 1304 @Nullable() 1305 public String getLogDuration() 1306 { 1307 return logDuration; 1308 } 1309 1310 1311 1312 /** 1313 * Retrieves the amount of data in kilobytes to capture from the beginning of 1314 * each log file that should be included in the support data archive. 1315 * 1316 * @return The amount of data in kilobytes to capture from the beginning of 1317 * each log file that should be included in the support data archive, 1318 * or {@code null} if the property should not be specified when the 1319 * task is created (in which case the server will determine an 1320 * appropriate amount of log content to include). 1321 */ 1322 @Nullable() 1323 public Integer getLogFileHeadCollectionSizeKB() 1324 { 1325 return logFileHeadCollectionSizeKB; 1326 } 1327 1328 1329 1330 /** 1331 * Retrieves the amount of data in kilobytes to capture from the end of each 1332 * log file that should be included in the support data archive. 1333 * 1334 * @return The amount of data in kilobytes to capture from the end of each 1335 * log file that should be included in the support data archive, or 1336 * {@code null} if the property should not be specified when the task 1337 * is created (in which case the server will determine an 1338 * appropriate amount of log content to include). 1339 */ 1340 @Nullable() 1341 public Integer getLogFileTailCollectionSizeKB() 1342 { 1343 return logFileTailCollectionSizeKB; 1344 } 1345 1346 1347 1348 /** 1349 * Retrieves a parsed value of the log duration in milliseconds. 1350 * 1351 * @return A parsed value of the log duration in milliseconds or {@code null} 1352 * if no log duration is set. 1353 * 1354 * @throws TaskException If the log duration value cannot be parsed as a 1355 * valid duration. 1356 */ 1357 @Nullable() 1358 public Long getLogDurationMillis() 1359 throws TaskException 1360 { 1361 if (logDuration == null) 1362 { 1363 return null; 1364 } 1365 1366 try 1367 { 1368 return DurationArgument.parseDuration(logDuration, TimeUnit.MILLISECONDS); 1369 } 1370 catch (final ArgumentException e) 1371 { 1372 Debug.debugException(e); 1373 throw new TaskException(e.getMessage(), e); 1374 } 1375 } 1376 1377 1378 1379 /** 1380 * Retrieves an additional comment that should be included in the support data 1381 * archive. 1382 * 1383 * @return An additional comment that should be included in the support data 1384 * archive, or {@code null} if no comment should be included. 1385 */ 1386 @Nullable() 1387 public String getComment() 1388 { 1389 return comment; 1390 } 1391 1392 1393 1394 /** 1395 * Retrieves the minimum number of existing support data archives that should 1396 * be retained. 1397 * 1398 * @return The minimum number of existing support data archives that should 1399 * be retained, or {@code null} if there is no minimum retain count. 1400 */ 1401 @Nullable() 1402 public Integer getRetainPreviousSupportDataArchiveCount() 1403 { 1404 return retainPreviousSupportDataArchiveCount; 1405 } 1406 1407 1408 1409 /** 1410 * Retrieves the minimum age of existing support data archives that should be 1411 * retained. 1412 * 1413 * @return The minimum age of existing support data archives that should 1414 * be retained, or {@code null} if there is no minimum retain age. 1415 */ 1416 @Nullable() 1417 public String getRetainPreviousSupportDataArchiveAge() 1418 { 1419 return retainPreviousSupportDataArchiveAge; 1420 } 1421 1422 1423 1424 /** 1425 * Retrieves a parsed value of the retain previous support data archive age in 1426 * milliseconds. 1427 * 1428 * @return A parsed value of the retain previous support data archive age in 1429 * milliseconds or {@code null} if no retain age is set. 1430 * 1431 * @throws TaskException If the retain age value cannot be parsed as a valid 1432 * duration. 1433 */ 1434 @Nullable() 1435 public Long getRetainPreviousSupportDataArchiveAgeMillis() 1436 throws TaskException 1437 { 1438 if (retainPreviousSupportDataArchiveAge == null) 1439 { 1440 return null; 1441 } 1442 1443 try 1444 { 1445 return DurationArgument.parseDuration( 1446 retainPreviousSupportDataArchiveAge, TimeUnit.MILLISECONDS); 1447 } 1448 catch (final ArgumentException e) 1449 { 1450 Debug.debugException(e); 1451 throw new TaskException(e.getMessage(), e); 1452 } 1453 } 1454 1455 1456 1457 /** 1458 * {@inheritDoc} 1459 */ 1460 @Override() 1461 @NotNull() 1462 protected List<String> getAdditionalObjectClasses() 1463 { 1464 return Collections.singletonList(OC_COLLECT_SUPPORT_DATA_TASK); 1465 } 1466 1467 1468 1469 /** 1470 * {@inheritDoc} 1471 */ 1472 @Override() 1473 @NotNull() 1474 protected List<Attribute> getAdditionalAttributes() 1475 { 1476 final List<Attribute> attrList = new ArrayList<>(15); 1477 1478 if (outputPath != null) 1479 { 1480 attrList.add(new Attribute(ATTR_OUTPUT_PATH, outputPath)); 1481 } 1482 1483 if (encryptionPassphraseFile != null) 1484 { 1485 attrList.add(new Attribute(ATTR_ENCRYPTION_PASSPHRASE_FILE, 1486 encryptionPassphraseFile)); 1487 } 1488 1489 if (includeExpensiveData != null) 1490 { 1491 attrList.add(new Attribute(ATTR_INCLUDE_EXPENSIVE_DATA, 1492 includeExpensiveData ? "TRUE" : "FALSE")); 1493 } 1494 1495 if (includeReplicationStateDump != null) 1496 { 1497 attrList.add(new Attribute(ATTR_INCLUDE_REPLICATION_STATE_DUMP, 1498 includeReplicationStateDump ? "TRUE" : "FALSE")); 1499 } 1500 1501 if (includeBinaryFiles != null) 1502 { 1503 attrList.add(new Attribute(ATTR_INCLUDE_BINARY_FILES, 1504 includeBinaryFiles ? "TRUE" : "FALSE")); 1505 } 1506 1507 if (includeExtensionSource != null) 1508 { 1509 attrList.add(new Attribute(ATTR_INCLUDE_EXTENSION_SOURCE, 1510 includeExtensionSource ? "TRUE" : "FALSE")); 1511 } 1512 1513 if (useSequentialMode != null) 1514 { 1515 attrList.add(new Attribute(ATTR_USE_SEQUENTIAL_MODE, 1516 useSequentialMode ? "TRUE" : "FALSE")); 1517 } 1518 1519 if (securityLevel != null) 1520 { 1521 attrList.add(new Attribute(ATTR_SECURITY_LEVEL, securityLevel.getName())); 1522 } 1523 1524 if (jstackCount != null) 1525 { 1526 attrList.add(new Attribute(ATTR_JSTACK_COUNT, 1527 String.valueOf(jstackCount))); 1528 } 1529 1530 if (reportCount != null) 1531 { 1532 attrList.add(new Attribute(ATTR_REPORT_COUNT, 1533 String.valueOf(reportCount))); 1534 } 1535 1536 if (reportIntervalSeconds != null) 1537 { 1538 attrList.add(new Attribute(ATTR_REPORT_INTERVAL_SECONDS, 1539 String.valueOf(reportIntervalSeconds))); 1540 } 1541 1542 if (logStartTime != null) 1543 { 1544 attrList.add(new Attribute(ATTR_LOG_START_TIME, 1545 StaticUtils.encodeGeneralizedTime(logStartTime))); 1546 } 1547 1548 if (logEndTime != null) 1549 { 1550 attrList.add(new Attribute(ATTR_LOG_END_TIME, 1551 StaticUtils.encodeGeneralizedTime(logEndTime))); 1552 } 1553 1554 if (logDuration != null) 1555 { 1556 attrList.add(new Attribute(ATTR_LOG_DURATION, logDuration)); 1557 } 1558 1559 if (logFileHeadCollectionSizeKB != null) 1560 { 1561 attrList.add(new Attribute(ATTR_LOG_FILE_HEAD_COLLECTION_SIZE_KB, 1562 String.valueOf(logFileHeadCollectionSizeKB))); 1563 } 1564 1565 if (logFileTailCollectionSizeKB != null) 1566 { 1567 attrList.add(new Attribute(ATTR_LOG_FILE_TAIL_COLLECTION_SIZE_KB, 1568 String.valueOf(logFileTailCollectionSizeKB))); 1569 } 1570 1571 if (comment != null) 1572 { 1573 attrList.add(new Attribute(ATTR_COMMENT, comment)); 1574 } 1575 1576 if (retainPreviousSupportDataArchiveCount != null) 1577 { 1578 attrList.add(new Attribute(ATTR_RETAIN_PREVIOUS_ARCHIVE_COUNT, 1579 String.valueOf(retainPreviousSupportDataArchiveCount))); 1580 } 1581 1582 if (retainPreviousSupportDataArchiveAge != null) 1583 { 1584 attrList.add(new Attribute(ATTR_RETAIN_PREVIOUS_ARCHIVE_AGE, 1585 retainPreviousSupportDataArchiveAge)); 1586 } 1587 1588 return attrList; 1589 } 1590 1591 1592 1593 /** 1594 * {@inheritDoc} 1595 */ 1596 @Override() 1597 @NotNull() 1598 public List<TaskProperty> getTaskSpecificProperties() 1599 { 1600 return Collections.unmodifiableList(Arrays.asList( 1601 PROPERTY_OUTPUT_PATH, 1602 PROPERTY_ENCRYPTION_PASSPHRASE_FILE, 1603 PROPERTY_INCLUDE_EXPENSIVE_DATA, 1604 PROPERTY_INCLUDE_REPLICATION_STATE_DUMP, 1605 PROPERTY_INCLUDE_BINARY_FILES, 1606 PROPERTY_INCLUDE_EXTENSION_SOURCE, 1607 PROPERTY_USE_SEQUENTIAL_MODE, 1608 PROPERTY_SECURITY_LEVEL, 1609 PROPERTY_JSTACK_COUNT, 1610 PROPERTY_REPORT_COUNT, 1611 PROPERTY_REPORT_INTERVAL_SECONDS, 1612 PROPERTY_LOG_START_TIME, 1613 PROPERTY_LOG_END_TIME, 1614 PROPERTY_LOG_DURATION, 1615 PROPERTY_LOG_FILE_HEAD_COLLECTION_SIZE_KB, 1616 PROPERTY_LOG_FILE_TAIL_COLLECTION_SIZE_KB, 1617 PROPERTY_COMMENT, 1618 PROPERTY_RETAIN_PREVIOUS_ARCHIVE_COUNT, 1619 PROPERTY_RETAIN_PREVIOUS_ARCHIVE_AGE)); 1620 } 1621 1622 1623 1624 /** 1625 * {@inheritDoc} 1626 */ 1627 @Override() 1628 @NotNull() 1629 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 1630 { 1631 final Map<TaskProperty,List<Object>> props = 1632 new LinkedHashMap<>(StaticUtils.computeMapCapacity(20)); 1633 1634 if (outputPath != null) 1635 { 1636 props.put(PROPERTY_OUTPUT_PATH, 1637 Collections.<Object>singletonList(outputPath)); 1638 } 1639 1640 if (encryptionPassphraseFile != null) 1641 { 1642 props.put(PROPERTY_ENCRYPTION_PASSPHRASE_FILE, 1643 Collections.<Object>singletonList(encryptionPassphraseFile)); 1644 } 1645 1646 if (includeExpensiveData != null) 1647 { 1648 props.put(PROPERTY_INCLUDE_EXPENSIVE_DATA, 1649 Collections.<Object>singletonList(includeExpensiveData)); 1650 } 1651 1652 if (includeReplicationStateDump != null) 1653 { 1654 props.put(PROPERTY_INCLUDE_REPLICATION_STATE_DUMP, 1655 Collections.<Object>singletonList(includeReplicationStateDump)); 1656 } 1657 1658 if (includeBinaryFiles != null) 1659 { 1660 props.put(PROPERTY_INCLUDE_BINARY_FILES, 1661 Collections.<Object>singletonList(includeBinaryFiles)); 1662 } 1663 1664 if (includeExtensionSource != null) 1665 { 1666 props.put(PROPERTY_INCLUDE_EXTENSION_SOURCE, 1667 Collections.<Object>singletonList(includeExtensionSource)); 1668 } 1669 1670 if (useSequentialMode != null) 1671 { 1672 props.put(PROPERTY_USE_SEQUENTIAL_MODE, 1673 Collections.<Object>singletonList(useSequentialMode)); 1674 } 1675 1676 if (securityLevel != null) 1677 { 1678 props.put(PROPERTY_SECURITY_LEVEL, 1679 Collections.<Object>singletonList(securityLevel.getName())); 1680 } 1681 1682 if (jstackCount != null) 1683 { 1684 props.put(PROPERTY_JSTACK_COUNT, 1685 Collections.<Object>singletonList(jstackCount.longValue())); 1686 } 1687 1688 if (reportCount != null) 1689 { 1690 props.put(PROPERTY_REPORT_COUNT, 1691 Collections.<Object>singletonList(reportCount.longValue())); 1692 } 1693 1694 if (reportIntervalSeconds != null) 1695 { 1696 props.put(PROPERTY_REPORT_INTERVAL_SECONDS, 1697 Collections.<Object>singletonList( 1698 reportIntervalSeconds.longValue())); 1699 } 1700 1701 if (logStartTime != null) 1702 { 1703 props.put(PROPERTY_LOG_START_TIME, 1704 Collections.<Object>singletonList(logStartTime)); 1705 } 1706 1707 if (logEndTime != null) 1708 { 1709 props.put(PROPERTY_LOG_END_TIME, 1710 Collections.<Object>singletonList(logEndTime)); 1711 } 1712 1713 if (logDuration != null) 1714 { 1715 props.put(PROPERTY_LOG_DURATION, 1716 Collections.<Object>singletonList(logDuration)); 1717 } 1718 1719 if (logFileHeadCollectionSizeKB != null) 1720 { 1721 props.put(PROPERTY_LOG_FILE_HEAD_COLLECTION_SIZE_KB, 1722 Collections.<Object>singletonList( 1723 logFileHeadCollectionSizeKB.longValue())); 1724 } 1725 1726 if (logFileTailCollectionSizeKB != null) 1727 { 1728 props.put(PROPERTY_LOG_FILE_TAIL_COLLECTION_SIZE_KB, 1729 Collections.<Object>singletonList( 1730 logFileTailCollectionSizeKB.longValue())); 1731 } 1732 1733 if (comment != null) 1734 { 1735 props.put(PROPERTY_COMMENT, 1736 Collections.<Object>singletonList(comment)); 1737 } 1738 1739 if (retainPreviousSupportDataArchiveCount != null) 1740 { 1741 props.put(PROPERTY_RETAIN_PREVIOUS_ARCHIVE_COUNT, 1742 Collections.<Object>singletonList( 1743 retainPreviousSupportDataArchiveCount.longValue())); 1744 } 1745 1746 if (retainPreviousSupportDataArchiveAge != null) 1747 { 1748 props.put(PROPERTY_RETAIN_PREVIOUS_ARCHIVE_AGE, 1749 Collections.<Object>singletonList( 1750 retainPreviousSupportDataArchiveAge)); 1751 } 1752 1753 props.putAll(super.getTaskPropertyValues()); 1754 return Collections.unmodifiableMap(props); 1755 } 1756}