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}