001/* 002 * Copyright 2008-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2008-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) 2015-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.monitors; 037 038 039 040import java.util.Collections; 041import java.util.Date; 042import java.util.LinkedHashMap; 043import java.util.List; 044import java.util.Map; 045 046import com.unboundid.ldap.sdk.Entry; 047import com.unboundid.util.NotMutable; 048import com.unboundid.util.StaticUtils; 049import com.unboundid.util.ThreadSafety; 050import com.unboundid.util.ThreadSafetyLevel; 051 052import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*; 053 054 055 056/** 057 * This class defines a monitor entry that provides general information about 058 * the state of the Directory Server. The general monitor entry is the 059 * top-level monitor entry that is generated by the monitor backend and is the 060 * parent of all monitor entries generated by the registered monitor providers. 061 * <BR> 062 * <BLOCKQUOTE> 063 * <B>NOTE:</B> This class, and other classes within the 064 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 065 * supported for use against Ping Identity, UnboundID, and 066 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 067 * for proprietary functionality or for external specifications that are not 068 * considered stable or mature enough to be guaranteed to work in an 069 * interoperable way with other types of LDAP servers. 070 * </BLOCKQUOTE> 071 * <BR> 072 * Information that may be included in the general monitor entry includes: 073 * <UL> 074 * <LI>The number of connections currently established to the server.</LI> 075 * <LI>The maximum number of connections that have been established at any one 076 * time.</LI> 077 * <LI>The total number of connections established to the server since 078 * startup.</LI> 079 * <LI>The time that the directory server was started.</LI> 080 * <LI>The current time on the server.</LI> 081 * <LI>The length of time in milliseconds that the server has been 082 * online.</LI> 083 * <LI>A user-friendly string that describes the length of time that the 084 * server has been online.</LI> 085 * <LI>The name of the directory server product.</LI> 086 * <LI>The name of the vendor that provides the directory server.</LI> 087 * <LI>The server version string.</LI> 088 * <LI>The DNs of the configuration entries for any third-party extensions 089 * loaded in the server.</LI> 090 * </UL> 091 * The server should present at most one general monitor entry. It can be 092 * retrieved using the {@link MonitorManager#getGeneralMonitorEntry} method. 093 * This entry provides specific methods for accessing information about the 094 * server (e.g., the 095 * {@link GeneralMonitorEntry#getCurrentConnections} method can be used 096 * to retrieve the number of connections currently established). Alternately, 097 * this information may be accessed using the generic API. See the 098 * {@link MonitorManager} class documentation for an example that demonstrates 099 * the use of the generic API for accessing monitor data. 100 */ 101@NotMutable() 102@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 103public final class GeneralMonitorEntry 104 extends MonitorEntry 105{ 106 /** 107 * The structural object class used in general monitor entries. 108 */ 109 static final String GENERAL_MONITOR_OC = "ds-general-monitor-entry"; 110 111 112 113 /** 114 * The name of the attribute that contains the name of the cluster in which 115 * the server is a member. 116 */ 117 private static final String ATTR_CLUSTER_NAME = "clusterName"; 118 119 120 121 /** 122 * The name of the attribute that contains the number of connections currently 123 * established to the server. 124 */ 125 private static final String ATTR_CURRENT_CONNECTIONS = "currentConnections"; 126 127 128 129 /** 130 * The name of the attribute that contains the Directory Server's current 131 * time. 132 */ 133 private static final String ATTR_CURRENT_TIME = "currentTime"; 134 135 136 137 /** 138 * The name of the attribute that contains the names of any alert types that 139 * have caused the server to be classified as "degraded". 140 */ 141 private static final String ATTR_DEGRADED_ALERT_TYPE = 142 "degraded-alert-type"; 143 144 145 146 /** 147 * The name of the attribute that contains the server instance name. 148 */ 149 private static final String ATTR_INSTANCE_NAME = "instanceName"; 150 151 152 153 /** 154 * The name of the attribute that contains the DN of the server's location 155 * config entry. 156 */ 157 private static final String ATTR_LOCATION_DN = "locationDN"; 158 159 160 161 /** 162 * The name of the attribute that contains the name of the server's location 163 * config entry. 164 */ 165 private static final String ATTR_LOCATION_NAME = "locationName"; 166 167 168 169 /** 170 * The name of the attribute that contains the maximum number of concurrent 171 * client connections established since startup. 172 */ 173 private static final String ATTR_MAX_CONNECTIONS = "maxConnections"; 174 175 176 177 /** 178 * The name of the attribute that contains the Directory Server product name. 179 */ 180 private static final String ATTR_PRODUCT_NAME = "productName"; 181 182 183 184 /** 185 * The name of the attribute that contains the UUID value that was generated 186 * when the server instance was initially created. 187 */ 188 private static final String ATTR_SERVER_UUID = "serverUUID"; 189 190 191 192 /** 193 * The name of the attribute that contains the Directory Server start time. 194 */ 195 private static final String ATTR_START_TIME = "startTime"; 196 197 198 199 /** 200 * The name of the attribute that contains the Directory Server startup ID. 201 */ 202 private static final String ATTR_STARTUP_ID = "startupID"; 203 204 205 206 /** 207 * The name of the attribute that contains the Directory Server startup UUID. 208 */ 209 private static final String ATTR_STARTUP_UUID = "startupUUID"; 210 211 212 213 /** 214 * The name of the attribute that holds the DNs of the configuration entries 215 * for any third-party extensions loaded in the server. 216 */ 217 private static final String ATTR_THIRD_PARTY_EXTENSION_DN = 218 "thirdPartyExtensionDN"; 219 220 221 222 /** 223 * The name of the attribute that contains the total number of connections 224 * that have been established since startup. 225 */ 226 private static final String ATTR_TOTAL_CONNECTIONS = "totalConnections"; 227 228 229 230 /** 231 * The name of the attribute that contains the Directory Server's uptime. 232 */ 233 private static final String ATTR_UP_TIME = "upTime"; 234 235 236 237 /** 238 * The name of the attribute that contains the Directory Server vendor name. 239 */ 240 private static final String ATTR_VENDOR_NAME = "productVendor"; 241 242 243 244 /** 245 * The name of the attribute that contains the Directory Server version 246 * string. 247 */ 248 private static final String ATTR_VERSION = "productVersion"; 249 250 251 252 /** 253 * The name of the attribute that contains the names of any alert types that 254 * have caused the server to be classified as "unavailable". 255 */ 256 private static final String ATTR_UNAVAILABLE_ALERT_TYPE = 257 "unavailable-alert-type"; 258 259 260 261 /** 262 * The serial version UID for this serializable class. 263 */ 264 private static final long serialVersionUID = 4262569940859462743L; 265 266 267 268 // The server's current time. 269 private final Date currentTime; 270 271 // The server's start time. 272 private final Date startTime; 273 274 // The names of the alert types that have caused the server to be classified 275 // as "degraded". 276 private final List<String> degradedAlertTypes; 277 278 // The DNs of the config entries for any third-party extensions loaded in the 279 // server. 280 private final List<String> thirdPartyExtensionDNs; 281 282 // The names of the alert types that have caused the server to be classified 283 // as "unavailable". 284 private final List<String> unavailableAlertTypes; 285 286 // The number connections currently established. 287 private final Long currentConnections; 288 289 // The maximum number connections established at any time since startup. 290 private final Long maxConnections; 291 292 // The total number of connections that have been established since startup. 293 private final Long totalConnections; 294 295 // The Directory Server cluster name. 296 private final String clusterName; 297 298 // The Directory Server instance name. 299 private final String instanceName; 300 301 // The DN of the Directory Server's location config entry. 302 private final String locationDN; 303 304 // The name of the Directory Server's location config entry. 305 private final String locationName; 306 307 // The Directory Server product name. 308 private final String productName; 309 310 // The UUID value that was generated when the server instance was initially 311 // created. 312 private final String serverUUID; 313 314 // The Directory Server startup ID. 315 private final String startupID; 316 317 // The Directory Server startup UUID. 318 private final String startupUUID; 319 320 // The string representation of the uptime. 321 private final String uptime; 322 323 // The Directory Server vendor name. 324 private final String vendorName; 325 326 // The Directory Server version string. 327 private final String versionString; 328 329 330 331 /** 332 * Creates a new general monitor entry from the provided entry. 333 * 334 * @param entry The entry to be parsed as a general monitor entry. It must 335 * not be {@code null}. 336 */ 337 public GeneralMonitorEntry(final Entry entry) 338 { 339 super(entry); 340 341 currentConnections = getLong(ATTR_CURRENT_CONNECTIONS); 342 currentTime = getDate(ATTR_CURRENT_TIME); 343 maxConnections = getLong(ATTR_MAX_CONNECTIONS); 344 productName = getString(ATTR_PRODUCT_NAME); 345 startTime = getDate(ATTR_START_TIME); 346 clusterName = getString(ATTR_CLUSTER_NAME); 347 instanceName = getString(ATTR_INSTANCE_NAME); 348 locationDN = getString(ATTR_LOCATION_DN); 349 locationName = getString(ATTR_LOCATION_NAME); 350 serverUUID = getString(ATTR_SERVER_UUID); 351 startupID = getString(ATTR_STARTUP_ID); 352 startupUUID = getString(ATTR_STARTUP_UUID); 353 totalConnections = getLong(ATTR_TOTAL_CONNECTIONS); 354 uptime = getString(ATTR_UP_TIME); 355 vendorName = getString(ATTR_VENDOR_NAME); 356 versionString = getString(ATTR_VERSION); 357 degradedAlertTypes = getStrings(ATTR_DEGRADED_ALERT_TYPE); 358 unavailableAlertTypes = getStrings(ATTR_UNAVAILABLE_ALERT_TYPE); 359 thirdPartyExtensionDNs = getStrings(ATTR_THIRD_PARTY_EXTENSION_DN); 360 } 361 362 363 364 /** 365 * Retrieves the number of connections currently established. 366 * 367 * @return The number of connections currently established, or {@code null} 368 * if it was not included in the monitor entry. 369 */ 370 public Long getCurrentConnections() 371 { 372 return currentConnections; 373 } 374 375 376 377 /** 378 * Retrieves the maximum number of concurrent connections established at any 379 * time since startup. 380 * 381 * @return The maximum number of concurrent connections established at any 382 * time since startup, or {@code null} if it was not included in the 383 * monitor entry. 384 */ 385 public Long getMaxConnections() 386 { 387 return maxConnections; 388 } 389 390 391 392 /** 393 * Retrieves the total number of connections established since startup. 394 * 395 * @return The total number of connections established since startup, or 396 * {@code null} if it was not included in the monitor entry. 397 */ 398 public Long getTotalConnections() 399 { 400 return totalConnections; 401 } 402 403 404 405 /** 406 * Retrieves the current time as reported by the Directory Server. 407 * 408 * @return The current time as reported by the Directory Server, or 409 * {@code null} if it was not included in the monitor entry. 410 */ 411 public Date getCurrentTime() 412 { 413 return currentTime; 414 } 415 416 417 418 /** 419 * Retrieves the time that the Directory Server was started. 420 * 421 * @return The time that the Directory Server was started, or {@code null} if 422 * it was not included in the monitor entry. 423 */ 424 public Date getStartTime() 425 { 426 return startTime; 427 } 428 429 430 431 /** 432 * Retrieves the name of the cluster in which the server is a member. 433 * 434 * @return The name of the cluster in which the server is a member, or 435 * {@code null} if it was not included in the monitor entry. 436 */ 437 public String getClusterName() 438 { 439 return clusterName; 440 } 441 442 443 444 /** 445 * Retrieves the name assigned to the Directory Server instance. 446 * 447 * @return The name assigned to the Directory Server instance, or 448 * {@code null} if it was not included in the monitor entry. 449 */ 450 public String getInstanceName() 451 { 452 return instanceName; 453 } 454 455 456 457 /** 458 * Retrieves the name of the configuration entry that defines the server's 459 * location. 460 * 461 * @return The name of the configuration entry that defines the server's 462 * location, or {@code null} if it was not included in the monitor 463 * entry. 464 */ 465 public String getLocationName() 466 { 467 return locationName; 468 } 469 470 471 472 /** 473 * Retrieves the DN of the configuration entry that defines the server's 474 * location. 475 * 476 * @return The DN of the configuration entry that defines the server's 477 * location, or {@code null} if it was not included in the monitor 478 * entry. 479 */ 480 public String getLocationDN() 481 { 482 return locationDN; 483 } 484 485 486 487 /** 488 * Retrieves the UUID value that was generated when the server instance was 489 * initially created. 490 * 491 * @return The UUID value that was generated when the server instance was 492 * initially created, or {@code null} if it was not included in the 493 * monitor entry. 494 */ 495 public String getServerUUID() 496 { 497 return serverUUID; 498 } 499 500 501 502 /** 503 * Retrieves a relatively compact identifier generated at the time the 504 * Directory Server was started. 505 * 506 * @return A relatively compact identifier generated at the time the 507 * Directory Server was started, or {@code null} if it was not 508 * included in the monitor entry. 509 */ 510 public String getStartupID() 511 { 512 return startupID; 513 } 514 515 516 517 /** 518 * Retrieves the UUID that was generated when the Directory Server was 519 * started. 520 * 521 * @return The UUID that was generated when the Directory Server was started, 522 * or {@code null} if it was not included in the monitor entry. 523 */ 524 public String getStartupUUID() 525 { 526 return startupUUID; 527 } 528 529 530 531 /** 532 * Retrieves the Directory Server uptime in milliseconds. 533 * 534 * @return The Directory Server uptime in milliseconds, or {@code null} if 535 * either the current time or the start time was not available. 536 */ 537 public Long getUptimeMillis() 538 { 539 if ((currentTime == null) || (startTime == null)) 540 { 541 return null; 542 } 543 544 return currentTime.getTime() - startTime.getTime(); 545 } 546 547 548 549 /** 550 * Retrieves the human-readable string representation of the Directory Server 551 * uptime. 552 * 553 * @return The human-readable string representation of the Directory Server 554 * uptime, or {@code null} if it was not included in the monitor 555 * entry. 556 */ 557 public String getUptimeString() 558 { 559 return uptime; 560 } 561 562 563 564 /** 565 * Retrieves the Directory Server product name. 566 * 567 * @return The Directory Serve product name, or {@code null} if it was not 568 * included in the monitor entry. 569 */ 570 public String getProductName() 571 { 572 return productName; 573 } 574 575 576 577 /** 578 * Retrieves the Directory Server vendor name string. 579 * 580 * @return The Directory Server vendor name string, or {@code null} if it 581 * was not included in the monitor entry. 582 */ 583 public String getVendorName() 584 { 585 return vendorName; 586 } 587 588 589 590 /** 591 * Retrieves the Directory Server version string. 592 * 593 * @return The Directory Server version string, or {@code null} if it was not 594 * included in the monitor entry. 595 */ 596 public String getVersionString() 597 { 598 return versionString; 599 } 600 601 602 603 /** 604 * Retrieves the names of any alert types which may have caused the server to 605 * be currently classified as "degraded". 606 * 607 * @return The names of any alert types which may have caused the server to 608 * be currently classified as "degraded", or an empty list if it was 609 * not included in the monitor entry (which likely indicates that the 610 * server is not classified as "degraded"). 611 */ 612 public List<String> getDegradedAlertTypes() 613 { 614 return degradedAlertTypes; 615 } 616 617 618 619 /** 620 * Retrieves the names of any alert types which may have caused the server to 621 * be currently classified as "unavailable". 622 * 623 * @return The names of any alert types which may have caused the server to 624 * be currently classified as "unavailable", or an empty list if it 625 * was not included in the monitor entry (which likely indicates that 626 * the server is not classified as "unavailable"). 627 */ 628 public List<String> getUnavailableAlertTypes() 629 { 630 return unavailableAlertTypes; 631 } 632 633 634 635 /** 636 * Retrieves the DNs of the configuration entries for any third-party 637 * extensions currently loaded in the server. 638 * 639 * @return The DNs of the configuration entries for any third-party 640 * extensions currently loaded in the server, or an empty list if it 641 * was not included in the monitor entry. 642 */ 643 public List<String> getThirdPartyExtensionDNs() 644 { 645 return thirdPartyExtensionDNs; 646 } 647 648 649 650 /** 651 * {@inheritDoc} 652 */ 653 @Override() 654 public String getMonitorDisplayName() 655 { 656 return INFO_GENERAL_MONITOR_DISPNAME.get(); 657 } 658 659 660 661 /** 662 * {@inheritDoc} 663 */ 664 @Override() 665 public String getMonitorDescription() 666 { 667 return INFO_GENERAL_MONITOR_DESC.get(); 668 } 669 670 671 672 /** 673 * {@inheritDoc} 674 */ 675 @Override() 676 public Map<String,MonitorAttribute> getMonitorAttributes() 677 { 678 final LinkedHashMap<String,MonitorAttribute> attrs = 679 new LinkedHashMap<>(StaticUtils.computeMapCapacity(30)); 680 681 if (productName != null) 682 { 683 addMonitorAttribute(attrs, 684 ATTR_PRODUCT_NAME, 685 INFO_GENERAL_DISPNAME_PRODUCT_NAME.get(), 686 INFO_GENERAL_DESC_PRODUCT_NAME.get(), 687 productName); 688 } 689 690 if (vendorName != null) 691 { 692 addMonitorAttribute(attrs, 693 ATTR_VENDOR_NAME, 694 INFO_GENERAL_DISPNAME_VENDOR_NAME.get(), 695 INFO_GENERAL_DESC_VENDOR_NAME.get(), 696 vendorName); 697 } 698 699 if (versionString != null) 700 { 701 addMonitorAttribute(attrs, 702 ATTR_VERSION, 703 INFO_GENERAL_DISPNAME_VERSION.get(), 704 INFO_GENERAL_DESC_VERSION.get(), 705 versionString); 706 } 707 708 if (clusterName != null) 709 { 710 addMonitorAttribute(attrs, 711 ATTR_CLUSTER_NAME, 712 INFO_GENERAL_DISPNAME_CLUSTER_NAME.get(), 713 INFO_GENERAL_DESC_CLUSTER_NAME.get(), 714 clusterName); 715 } 716 717 if (instanceName != null) 718 { 719 addMonitorAttribute(attrs, 720 ATTR_INSTANCE_NAME, 721 INFO_GENERAL_DISPNAME_INSTANCE_NAME.get(), 722 INFO_GENERAL_DESC_INSTANCE_NAME.get(), 723 instanceName); 724 } 725 726 if (locationName != null) 727 { 728 addMonitorAttribute(attrs, 729 ATTR_LOCATION_NAME, 730 INFO_GENERAL_DISPNAME_LOCATION_NAME.get(), 731 INFO_GENERAL_DESC_LOCATION_NAME.get(), 732 locationName); 733 } 734 735 if (locationDN != null) 736 { 737 addMonitorAttribute(attrs, 738 ATTR_LOCATION_DN, 739 INFO_GENERAL_DISPNAME_LOCATION_DN.get(), 740 INFO_GENERAL_DESC_LOCATION_DN.get(), 741 locationDN); 742 } 743 744 if (startTime != null) 745 { 746 addMonitorAttribute(attrs, 747 ATTR_START_TIME, 748 INFO_GENERAL_DISPNAME_START_TIME.get(), 749 INFO_GENERAL_DESC_START_TIME.get(), 750 startTime); 751 } 752 753 if (serverUUID != null) 754 { 755 addMonitorAttribute(attrs, 756 ATTR_SERVER_UUID, 757 INFO_GENERAL_DISPNAME_SERVER_UUID.get(), 758 INFO_GENERAL_DESC_SERVER_UUID.get(), 759 serverUUID); 760 } 761 762 if (startupID != null) 763 { 764 addMonitorAttribute(attrs, 765 ATTR_STARTUP_ID, 766 INFO_GENERAL_DISPNAME_STARTUP_ID.get(), 767 INFO_GENERAL_DESC_STARTUP_ID.get(), 768 startupID); 769 } 770 771 if (startupUUID != null) 772 { 773 addMonitorAttribute(attrs, 774 ATTR_STARTUP_UUID, 775 INFO_GENERAL_DISPNAME_STARTUP_UUID.get(), 776 INFO_GENERAL_DESC_STARTUP_UUID.get(), 777 startupUUID); 778 } 779 780 if (currentTime != null) 781 { 782 addMonitorAttribute(attrs, 783 ATTR_CURRENT_TIME, 784 INFO_GENERAL_DISPNAME_CURRENT_TIME.get(), 785 INFO_GENERAL_DESC_CURRENT_TIME.get(), 786 currentTime); 787 } 788 789 if (uptime != null) 790 { 791 addMonitorAttribute(attrs, 792 ATTR_UP_TIME, 793 INFO_GENERAL_DISPNAME_UPTIME.get(), 794 INFO_GENERAL_DESC_UPTIME.get(), 795 uptime); 796 } 797 798 if ((startTime != null) && (currentTime != null)) 799 { 800 addMonitorAttribute(attrs, 801 "upTimeMillis", 802 INFO_GENERAL_DISPNAME_UPTIME_MILLIS.get(), 803 INFO_GENERAL_DESC_UPTIME_MILLIS.get(), 804 Long.valueOf(currentTime.getTime() - startTime.getTime())); 805 } 806 807 if (currentConnections != null) 808 { 809 addMonitorAttribute(attrs, 810 ATTR_CURRENT_CONNECTIONS, 811 INFO_GENERAL_DISPNAME_CURRENT_CONNECTIONS.get(), 812 INFO_GENERAL_DESC_CURRENT_CONNECTIONS.get(), 813 currentConnections); 814 } 815 816 if (maxConnections != null) 817 { 818 addMonitorAttribute(attrs, 819 ATTR_MAX_CONNECTIONS, 820 INFO_GENERAL_DISPNAME_MAX_CONNECTIONS.get(), 821 INFO_GENERAL_DESC_MAX_CONNECTIONS.get(), 822 maxConnections); 823 } 824 825 if (totalConnections != null) 826 { 827 addMonitorAttribute(attrs, 828 ATTR_TOTAL_CONNECTIONS, 829 INFO_GENERAL_DISPNAME_TOTAL_CONNECTIONS.get(), 830 INFO_GENERAL_DESC_TOTAL_CONNECTIONS.get(), 831 totalConnections); 832 } 833 834 if (! degradedAlertTypes.isEmpty()) 835 { 836 addMonitorAttribute(attrs, 837 ATTR_DEGRADED_ALERT_TYPE, 838 INFO_GENERAL_DISPNAME_DEGRADED_ALERT_TYPE.get(), 839 INFO_GENERAL_DESC_DEGRADED_ALERT_TYPE.get(), 840 degradedAlertTypes); 841 } 842 843 if (! unavailableAlertTypes.isEmpty()) 844 { 845 addMonitorAttribute(attrs, 846 ATTR_UNAVAILABLE_ALERT_TYPE, 847 INFO_GENERAL_DISPNAME_UNAVAILABLE_ALERT_TYPE.get(), 848 INFO_GENERAL_DESC_UNAVAILABLE_ALERT_TYPE.get(), 849 unavailableAlertTypes); 850 } 851 852 if (! thirdPartyExtensionDNs.isEmpty()) 853 { 854 addMonitorAttribute(attrs, 855 ATTR_THIRD_PARTY_EXTENSION_DN, 856 INFO_GENERAL_DISPNAME_THIRD_PARTY_EXTENSION_DN.get(), 857 INFO_GENERAL_DESC_THIRD_PARTY_EXTENSION_DN.get(), 858 thirdPartyExtensionDNs); 859 } 860 861 return Collections.unmodifiableMap(attrs); 862 } 863}