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