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