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