001/*
002 * Copyright 2008-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2018 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk.unboundidds.monitors;
022
023
024
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.LinkedHashMap;
028import java.util.List;
029import java.util.Map;
030
031import com.unboundid.ldap.sdk.Entry;
032import com.unboundid.util.NotMutable;
033import com.unboundid.util.ThreadSafety;
034import com.unboundid.util.ThreadSafetyLevel;
035
036import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
037
038
039
040/**
041 * This class defines a monitor entry that provides information about the system
042 * and JVM on which the Directory Server is running.
043 * <BR>
044 * <BLOCKQUOTE>
045 *   <B>NOTE:</B>  This class, and other classes within the
046 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
047 *   supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661
048 *   server products.  These classes provide support for proprietary
049 *   functionality or for external specifications that are not considered stable
050 *   or mature enough to be guaranteed to work in an interoperable way with
051 *   other types of LDAP servers.
052 * </BLOCKQUOTE>
053 * <BR>
054 * The information that may be available includes:
055 * <UL>
056 *   <LI>The name of the operating system on which the server is running.</LI>
057 *   <LI>The number of CPUs available to the JVM.</LI>
058 *   <LI>The Java classpath in use by the server.</LI>
059 *   <LI>The amount of memory currently used by the JVM.</LI>
060 *   <LI>The maximum amount of memory that the JVM will be allowed to use.</LI>
061 *   <LI>The amount of memory held by the JVM that is marked as "free" and can
062 *       be used to allocate new objects.</LI>
063 *   <LI>The hostname for the underlying system.</LI>
064 *   <LI>The location in which the server is installed on the
065 *       underlying system.</LI>
066 *   <LI>The current working directory for the server process.</LI>
067 *   <LI>The path to the Java installation being used to run the server.</LI>
068 *   <LI>The vendor that provides the Java installation being used to run the
069 *       server.</LI>
070 *   <LI>The Java version string for the Java installation being used to run
071 *       the server.</LI>
072 *   <LI>The vendor that provides the JVM being used by the Java installation
073 *       being used to run the server.</LI>
074 *   <LI>The JVM version string for the Java installation being used to run the
075 *       server.</LI>
076 *   <LI>The JVM architecture data model (i.e., whether it is a 32-bit or 64-bit
077 *       JVM).</LI>
078 *   <LI>The arguments provided to the JVM when running the server.</LI>
079 * </UL>
080 * The server should present at most one system info monitor entry.  It can be
081 * retrieved using the {@link MonitorManager#getSystemInfoMonitorEntry} method.
082 * This entry provides specific methods for accessing this system information
083 * (e.g., the {@link SystemInfoMonitorEntry#getOperatingSystem}
084 * method can be used to retrieve the name of the operating system).
085 * Alternately, this information may be accessed using the generic API.  See the
086 * {@link MonitorManager} class documentation for an example that demonstrates
087 * the use of the generic API for accessing monitor data.
088 */
089@NotMutable()
090@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
091public final class SystemInfoMonitorEntry
092       extends MonitorEntry
093{
094  /**
095   * The structural object class used in system info monitor entries.
096   */
097  static final String SYSTEM_INFO_MONITOR_OC =
098       "ds-system-info-monitor-entry";
099
100
101
102  /**
103   * The name of the attribute that provides the number of CPUs available to the
104   * JVM.
105   */
106  private static final String ATTR_AVAILABLE_CPUS = "availableCPUs";
107
108
109
110  /**
111   * The name of the attribute that provides the server Java classpath.
112   */
113  private static final String ATTR_CLASSPATH = "classPath";
114
115
116
117  /**
118   * The name of the attribute that provides the environment variables defined
119   * for the server process.
120   */
121  private static final String ATTR_ENVIRONMENT_VARIABLE = "environmentVariable";
122
123
124
125  /**
126   * The name of the attribute that provides the amount of free memory within
127   * the JVM.
128   */
129  private static final String ATTR_FREE_MEMORY = "freeUsedMemory";
130
131
132
133  /**
134   * The name of the attribute that provides the system hostname.
135   */
136  private static final String ATTR_HOSTNAME = "systemName";
137
138
139
140  /**
141   * The name of the attribute that provides the server instance root.
142   */
143  private static final String ATTR_INSTANCE_ROOT = "instanceRoot";
144
145
146
147  /**
148   * The name of the attribute that provides the server Java home.
149   */
150  private static final String ATTR_JAVA_HOME = "javaHome";
151
152
153
154  /**
155   * The name of the attribute that provides the server Java vendor.
156   */
157  private static final String ATTR_JAVA_VENDOR = "javaVendor";
158
159
160
161  /**
162   * The name of the attribute that provides the server Java version.
163   */
164  private static final String ATTR_JAVA_VERSION = "javaVersion";
165
166
167
168  /**
169   * The name of the attribute that provides the server JVM architecture (e.g.,
170   * 32-bit / 64-bit).
171   */
172  private static final String ATTR_JVM_ARCHITECTURE = "jvmArchitecture";
173
174
175
176  /**
177   * The name of the attribute that provides the set of arguments provided when
178   * starting the JVM.
179   */
180  private static final String ATTR_JVM_ARGUMENTS = "jvmArguments";
181
182
183
184  /**
185   * The name of the attribute that provides the process ID of the JVM in which
186   * the server is running.
187   */
188  private static final String ATTR_JVM_PID = "jvmPID";
189
190
191
192  /**
193   * The name of the attribute that provides the server JVM vendor.
194   */
195  private static final String ATTR_JVM_VENDOR = "jvmVendor";
196
197
198
199  /**
200   * The name of the attribute that provides the server JVM version.
201   */
202  private static final String ATTR_JVM_VERSION = "jvmVersion";
203
204
205
206  /**
207   * The name of the attribute that provides the maximum amount of memory
208   * available to the JVM.
209   */
210  private static final String ATTR_MAX_MEMORY = "maxMemory";
211
212
213
214  /**
215   * The name of the attribute that provides information about the server's
216   * operating system.
217   */
218  private static final String ATTR_OPERATING_SYSTEM = "operatingSystem";
219
220
221
222  /**
223   * The name of the attribute that provides the name of the default SSL context
224   * protocol that has been selected by the server.
225   */
226  private static final String ATTR_SSL_CONTEXT_PROTOCOL = "sslContextProtocol";
227
228
229
230  /**
231   * The name of the attribute that provides the set of system properties
232   * defined in the JVM.
233   */
234  private static final String ATTR_SYSTEM_PROPERTY = "systemProperty";
235
236
237
238  /**
239   * The name of the attribute that provides the amount of memory currently used
240   * by the JVM.
241   */
242  private static final String ATTR_USED_MEMORY = "usedMemory";
243
244
245
246  /**
247   * The name of the attribute that provides the name of the user as whom the
248   * server is running.
249   */
250  private static final String ATTR_USER_NAME = "userName";
251
252
253
254  /**
255   * The name of the attribute that provides the server working directory.
256   */
257  private static final String ATTR_WORKING_DIRECTORY = "workingDirectory";
258
259
260
261  /**
262   * The serial version UID for this serializable class.
263   */
264  private static final long serialVersionUID = 2709857663883498069L;
265
266
267
268  // The number of available CPUs.
269  private final Long availableCPUs;
270
271  // The amount of free memory held by the JVM.
272  private final Long freeMemory;
273
274  // The PID of the JVM in which the server is running.
275  private final Long jvmPID;
276
277  // The maximum amount of memory the JVM can use.
278  private final Long maxMemory;
279
280  // The amount of memory currently held by the JVM.
281  private final Long usedMemory;
282
283  // The set of environment variables defined in the server process.
284  private final Map<String,String> environmentVariables;
285
286  // The set of system properties defined in the JVM.
287  private final Map<String,String> systemProperties;
288
289  // The server's classpath.
290  private final String classpath;
291
292  // The server's hostname.
293  private final String hostname;
294
295  // The path to the server instance root.
296  private final String instanceRoot;
297
298  // The server's Java home.
299  private final String javaHome;
300
301  // The server's Java vendor string.
302  private final String javaVendor;
303
304  // The server's Java version string.
305  private final String javaVersion;
306
307  // The server's JVM architecture.
308  private final String jvmArchitecture;
309
310  // The set of arguments provided to the JVM.
311  private final String jvmArguments;
312
313  // The server's JVM vendor string.
314  private final String jvmVendor;
315
316  // The server's JVM version string.
317  private final String jvmVersion;
318
319  // The name of the operating system on which the server is running.
320  private final String operatingSystem;
321
322  // The name of the default SSL context protocol that has been selected by the
323  // server.
324  private final String sslContextProtocol;
325
326  // The name of the user as whom the server is running.
327  private final String userName;
328
329  // The path to the server's current working directory.
330  private final String workingDirectory;
331
332
333
334  /**
335   * Creates a new system info monitor entry from the provided entry.
336   *
337   * @param  entry  The entry to be parsed as a system info monitor entry.  It
338   *                must not be {@code null}.
339   */
340  public SystemInfoMonitorEntry(final Entry entry)
341  {
342    super(entry);
343
344    availableCPUs      = getLong(ATTR_AVAILABLE_CPUS);
345    classpath          = getString(ATTR_CLASSPATH);
346    freeMemory         = getLong(ATTR_FREE_MEMORY);
347    hostname           = getString(ATTR_HOSTNAME);
348    instanceRoot       = getString(ATTR_INSTANCE_ROOT);
349    javaHome           = getString(ATTR_JAVA_HOME);
350    javaVendor         = getString(ATTR_JAVA_VENDOR);
351    javaVersion        = getString(ATTR_JAVA_VERSION);
352    jvmArchitecture    = getString(ATTR_JVM_ARCHITECTURE);
353    jvmArguments       = getString(ATTR_JVM_ARGUMENTS);
354    jvmPID             = getLong(ATTR_JVM_PID);
355    jvmVendor          = getString(ATTR_JVM_VENDOR);
356    jvmVersion         = getString(ATTR_JVM_VERSION);
357    maxMemory          = getLong(ATTR_MAX_MEMORY);
358    operatingSystem    = getString(ATTR_OPERATING_SYSTEM);
359    sslContextProtocol = getString(ATTR_SSL_CONTEXT_PROTOCOL);
360    usedMemory         = getLong(ATTR_USED_MEMORY);
361    userName           = getString(ATTR_USER_NAME);
362    workingDirectory   = getString(ATTR_WORKING_DIRECTORY);
363
364    final List<String> envValues = getStrings(ATTR_ENVIRONMENT_VARIABLE);
365    final LinkedHashMap<String,String> envMap =
366         new LinkedHashMap<String,String>(envValues.size());
367    for (final String s : envValues)
368    {
369      final int eqPos = s.indexOf("='");
370      if (eqPos > 0)
371      {
372        final String name = s.substring(0, eqPos);
373        if (eqPos != (s.length() - 2))
374        {
375          envMap.put(name, s.substring(eqPos+2, (s.length() - 1)));
376        }
377      }
378    }
379    environmentVariables = Collections.unmodifiableMap(envMap);
380
381    final List<String> propValues = getStrings(ATTR_SYSTEM_PROPERTY);
382    final LinkedHashMap<String,String> propMap =
383         new LinkedHashMap<String,String>(propValues.size());
384    for (final String s : propValues)
385    {
386      final int eqPos = s.indexOf("='");
387      if (eqPos > 0)
388      {
389        final String name = s.substring(0, eqPos);
390        if (eqPos != (s.length() - 2))
391        {
392          propMap.put(name, s.substring(eqPos+2, (s.length() - 1)));
393        }
394      }
395    }
396    systemProperties = Collections.unmodifiableMap(propMap);
397  }
398
399
400
401  /**
402   * Retrieves the number of CPUs available to the JVM.
403   *
404   * @return  The number of CPUs available to the JVM, or {@code null} if it was
405   *          not included in the monitor entry.
406   */
407  public Long getAvailableCPUs()
408  {
409    return availableCPUs;
410  }
411
412
413
414  /**
415   * Retrieves the server's Java classpath.
416   *
417   * @return  The server's Java classpath, or {@code null} if it was not
418   *          included in the monitor entry.
419   */
420  public String getClassPath()
421  {
422    return classpath;
423  }
424
425
426
427  /**
428   * Retrieves the environment variables available to the server process, mapped
429   * from variable name to the corresponding value.
430   *
431   * @return  The environment variables available to the server process, or an
432   *          empty map if it was not included in the monitor entry.
433   */
434  public Map<String,String> getEnvironmentVariables()
435  {
436    return environmentVariables;
437  }
438
439
440
441  /**
442   * Retrieves the amount of memory in bytes held by the JVM that is currently
443   * marked as free.
444   *
445   * @return  The amount of memory in bytes held by the JVM that is currently
446   *          marked as free, or {@code null} if it was not included in the
447   *          monitor entry.
448   */
449  public Long getFreeMemory()
450  {
451    return freeMemory;
452  }
453
454
455
456  /**
457   * Retrieves the server's hostname.
458   *
459   * @return  The server's hostname, or {@code null} if it was not included in
460   *          the monitor entry.
461   */
462  public String getHostname()
463  {
464    return hostname;
465  }
466
467
468
469  /**
470   * Retrieves the path to the directory in which the Directory Server is
471   * installed.
472   *
473   * @return  The path to the directory in which the Directory Server is
474   *          installed, or {@code null} if it was not included in the monitor
475   *          entry.
476   */
477  public String getInstanceRoot()
478  {
479    return instanceRoot;
480  }
481
482
483
484  /**
485   * Retrieves the path to the Java installation used by the server.
486   *
487   * @return  The path to the Java installation used by the server, or
488   *          {@code null} if it was not included in the monitor entry.
489   */
490  public String getJavaHome()
491  {
492    return javaHome;
493  }
494
495
496
497  /**
498   * Retrieves the server's Java vendor string.
499   *
500   * @return  The server's Java vendor string, or {@code null} if it was not
501   *          included in the monitor entry.
502   */
503  public String getJavaVendor()
504  {
505    return javaVendor;
506  }
507
508
509
510  /**
511   * Retrieves the server's Java version string.
512   *
513   * @return  The server's Java version string, or {@code null} if it was not
514   *          included in the monitor entry.
515   */
516  public String getJavaVersion()
517  {
518    return javaVersion;
519  }
520
521
522
523  /**
524   * Retrieves the server's JVM architecture data mode, which should indicate
525   * whether the server is running a 32-bit or 64-bit JVM.
526   *
527   * @return  The server's JVM architecture data model, or {@code null} if it
528   *          was not included in the monitor entry.
529   */
530  public String getJVMArchitectureDataModel()
531  {
532    return jvmArchitecture;
533  }
534
535
536
537  /**
538   * Retrieves a list of the arguments provided to the JVM when the server was
539   * started.
540   *
541   * @return  A list of the arguments provided to the JVM when the server was
542   *          started, or {@code null} if it was not included in the monitor
543   *          entry.
544   */
545  public String getJVMArguments()
546  {
547    return jvmArguments;
548  }
549
550
551
552  /**
553   * Retrieves the process ID of the JVM in which the server is running.
554   *
555   * @return  The process ID of the JVM in which the server is running, or
556   *          {@code null} if it was not included in the monitor entry.
557   */
558  public Long getJVMPID()
559  {
560    return jvmPID;
561  }
562
563
564
565  /**
566   * Retrieves the server's JVM vendor string.
567   *
568   * @return  The server's JVM vendor string, or {@code null} if it was not
569   *          included in the monitor entry.
570   */
571  public String getJVMVendor()
572  {
573    return jvmVendor;
574  }
575
576
577
578  /**
579   * Retrieves the server's JVM version string.
580   *
581   * @return  The server's JVM version string, or {@code null} if it was not
582   *          included in the monitor entry.
583   */
584  public String getJVMVersion()
585  {
586    return jvmVersion;
587  }
588
589
590
591  /**
592   * Retrieves the maximum amount of memory in bytes that the JVM will be
593   * allowed to use.
594   *
595   * @return  The maximum amount of memory in bytes that the JVM will be allowed
596   *          to use, or {@code null} if it was not included in the monitor
597   *          entry.
598   */
599  public Long getMaxMemory()
600  {
601    return maxMemory;
602  }
603
604
605
606  /**
607   * Retrieves information about the operating system on which the server is
608   * running.
609   *
610   * @return  Information about the operating system on which the server is
611   *          running, or {@code null} if it was not included in the monitor
612   *          entry.
613   */
614  public String getOperatingSystem()
615  {
616    return operatingSystem;
617  }
618
619
620
621  /**
622   * Retrieves the name of the default SSL context protocol that has been
623   * selected by the server.
624   *
625   * @return  The name of the default SSL context protocol that has been
626   *          selected by the server.
627   */
628  public String getSSLContextProtocol()
629  {
630    return sslContextProtocol;
631  }
632
633
634
635  /**
636   * Retrieves the system properties defined in the server JVM, mapped from
637   * property name to the corresponding value.
638   *
639   * @return  The system properties defined in the server JVM, or an empty map
640   *          if it was not included in the monitor entry.
641   */
642  public Map<String,String> getSystemProperties()
643  {
644    return systemProperties;
645  }
646
647
648
649  /**
650   * Retrieves the amount of memory in bytes currently held by the JVM used to
651   * run the server.
652   *
653   * @return  The amount of memory in bytes currently held by the JVM used to
654   *          run the server, or {@code null} if it was not included in the
655   *          monitor entry
656   */
657  public Long getUsedMemory()
658  {
659    return usedMemory;
660  }
661
662
663
664  /**
665   * Retrieves the name of the user as whom the server is running.
666   *
667   * @return  The name of the user as whom the server is running, or
668   *          {@code null} if it was not included in the monitor entry.
669   */
670  public String getUserName()
671  {
672    return userName;
673  }
674
675
676
677  /**
678   * Retrieves the path to the server's current working directory.  This is
679   * generally the path to the directory from which the server was started.
680   *
681   * @return  The path to the server's current working directory, or
682   *          {@code null} if it was not included in the monitor entry.
683   */
684  public String getWorkingDirectory()
685  {
686    return workingDirectory;
687  }
688
689
690
691  /**
692   * {@inheritDoc}
693   */
694  @Override()
695  public String getMonitorDisplayName()
696  {
697    return INFO_SYSTEM_INFO_MONITOR_DISPNAME.get();
698  }
699
700
701
702  /**
703   * {@inheritDoc}
704   */
705  @Override()
706  public String getMonitorDescription()
707  {
708    return INFO_SYSTEM_INFO_MONITOR_DESC.get();
709  }
710
711
712
713  /**
714   * {@inheritDoc}
715   */
716  @Override()
717  public Map<String,MonitorAttribute> getMonitorAttributes()
718  {
719    final LinkedHashMap<String,MonitorAttribute> attrs =
720         new LinkedHashMap<String,MonitorAttribute>();
721
722    if (hostname != null)
723    {
724      addMonitorAttribute(attrs,
725           ATTR_HOSTNAME,
726           INFO_SYSTEM_INFO_DISPNAME_HOSTNAME.get(),
727           INFO_SYSTEM_INFO_DESC_HOSTNAME.get(),
728           hostname);
729    }
730
731    if (operatingSystem != null)
732    {
733      addMonitorAttribute(attrs,
734           ATTR_OPERATING_SYSTEM,
735           INFO_SYSTEM_INFO_DISPNAME_OPERATING_SYSTEM.get(),
736           INFO_SYSTEM_INFO_DESC_OPERATING_SYSTEM.get(),
737           operatingSystem);
738    }
739
740    if (jvmArchitecture != null)
741    {
742      addMonitorAttribute(attrs,
743           ATTR_JVM_ARCHITECTURE,
744           INFO_SYSTEM_INFO_DISPNAME_JVM_ARCHITECTURE.get(),
745           INFO_SYSTEM_INFO_DESC_JVM_ARCHITECTURE.get(),
746           jvmArchitecture);
747    }
748
749    if (javaHome != null)
750    {
751      addMonitorAttribute(attrs,
752           ATTR_JAVA_HOME,
753           INFO_SYSTEM_INFO_DISPNAME_JAVA_HOME.get(),
754           INFO_SYSTEM_INFO_DESC_JAVA_HOME.get(),
755           javaHome);
756    }
757
758    if (javaVersion != null)
759    {
760      addMonitorAttribute(attrs,
761           ATTR_JAVA_VERSION,
762           INFO_SYSTEM_INFO_DISPNAME_JAVA_VERSION.get(),
763           INFO_SYSTEM_INFO_DESC_JAVA_VERSION.get(),
764           javaVersion);
765    }
766
767    if (javaVendor != null)
768    {
769      addMonitorAttribute(attrs,
770           ATTR_JAVA_VENDOR,
771           INFO_SYSTEM_INFO_DISPNAME_JAVA_VENDOR.get(),
772           INFO_SYSTEM_INFO_DESC_JAVA_VENDOR.get(),
773           javaVendor);
774    }
775
776    if (jvmVersion != null)
777    {
778      addMonitorAttribute(attrs,
779           ATTR_JVM_VERSION,
780           INFO_SYSTEM_INFO_DISPNAME_JVM_VERSION.get(),
781           INFO_SYSTEM_INFO_DESC_JVM_VERSION.get(),
782           jvmVersion);
783    }
784
785    if (jvmVendor != null)
786    {
787      addMonitorAttribute(attrs,
788           ATTR_JVM_VENDOR,
789           INFO_SYSTEM_INFO_DISPNAME_JVM_VENDOR.get(),
790           INFO_SYSTEM_INFO_DESC_JVM_VENDOR.get(),
791           jvmVendor);
792    }
793
794    if (jvmArguments != null)
795    {
796      addMonitorAttribute(attrs,
797           ATTR_JVM_ARGUMENTS,
798           INFO_SYSTEM_INFO_DISPNAME_JVM_ARGUMENTS.get(),
799           INFO_SYSTEM_INFO_DESC_JVM_ARGUMENTS.get(),
800           jvmArguments);
801    }
802
803    if (jvmPID != null)
804    {
805      addMonitorAttribute(attrs,
806           ATTR_JVM_PID,
807           INFO_SYSTEM_INFO_DISPNAME_JVM_PID.get(),
808           INFO_SYSTEM_INFO_DESC_JVM_PID.get(),
809           jvmPID);
810    }
811
812    if (sslContextProtocol != null)
813    {
814      addMonitorAttribute(attrs,
815           ATTR_SSL_CONTEXT_PROTOCOL,
816           INFO_SYSTEM_INFO_DISPNAME_SSL_CONTEXT_PROTOCOL.get(),
817           INFO_SYSTEM_INFO_DESC_SSL_CONTEXT_PROTOCOL.get(),
818           sslContextProtocol);
819    }
820
821    if (classpath != null)
822    {
823      addMonitorAttribute(attrs,
824           ATTR_CLASSPATH,
825           INFO_SYSTEM_INFO_DISPNAME_CLASSPATH.get(),
826           INFO_SYSTEM_INFO_DESC_CLASSPATH.get(),
827           classpath);
828    }
829
830    if (instanceRoot != null)
831    {
832      addMonitorAttribute(attrs,
833           ATTR_INSTANCE_ROOT,
834           INFO_SYSTEM_INFO_DISPNAME_INSTANCE_ROOT.get(),
835           INFO_SYSTEM_INFO_DESC_INSTANCE_ROOT.get(),
836           instanceRoot);
837    }
838
839    if (workingDirectory != null)
840    {
841      addMonitorAttribute(attrs,
842           ATTR_WORKING_DIRECTORY,
843           INFO_SYSTEM_INFO_DISPNAME_WORKING_DIRECTORY.get(),
844           INFO_SYSTEM_INFO_DESC_WORKING_DIRECTORY.get(),
845           workingDirectory);
846    }
847
848    if (availableCPUs != null)
849    {
850      addMonitorAttribute(attrs,
851           ATTR_AVAILABLE_CPUS,
852           INFO_SYSTEM_INFO_DISPNAME_AVAILABLE_CPUS.get(),
853           INFO_SYSTEM_INFO_DESC_AVAILABLE_CPUS.get(),
854           availableCPUs);
855    }
856
857    if (usedMemory != null)
858    {
859      addMonitorAttribute(attrs,
860           ATTR_USED_MEMORY,
861           INFO_SYSTEM_INFO_DISPNAME_USED_MEMORY.get(),
862           INFO_SYSTEM_INFO_DESC_USED_MEMORY.get(),
863           usedMemory);
864    }
865
866    if (maxMemory != null)
867    {
868      addMonitorAttribute(attrs,
869           ATTR_MAX_MEMORY,
870           INFO_SYSTEM_INFO_DISPNAME_MAX_MEMORY.get(),
871           INFO_SYSTEM_INFO_DESC_MAX_MEMORY.get(),
872           maxMemory);
873    }
874
875    if (freeMemory != null)
876    {
877      addMonitorAttribute(attrs,
878           ATTR_FREE_MEMORY,
879           INFO_SYSTEM_INFO_DISPNAME_FREE_MEMORY.get(),
880           INFO_SYSTEM_INFO_DESC_FREE_MEMORY.get(),
881           freeMemory);
882    }
883
884    if (userName != null)
885    {
886      addMonitorAttribute(attrs,
887           ATTR_USER_NAME,
888           INFO_SYSTEM_INFO_DISPNAME_USER_NAME.get(),
889           INFO_SYSTEM_INFO_DESC_USER_NAME.get(),
890           userName);
891    }
892
893    if (! environmentVariables.isEmpty())
894    {
895      final ArrayList<String> envList =
896           new ArrayList<String>(environmentVariables.size());
897      for (final Map.Entry<String,String> e : environmentVariables.entrySet())
898      {
899        envList.add(e.getKey() + "='" + e.getValue() + '\'');
900      }
901
902      addMonitorAttribute(attrs,
903           ATTR_ENVIRONMENT_VARIABLE,
904           INFO_SYSTEM_INFO_DISPNAME_ENV_VAR.get(),
905           INFO_SYSTEM_INFO_DESC_ENV_VAR.get(),
906           envList);
907    }
908
909    if (! systemProperties.isEmpty())
910    {
911      final ArrayList<String> propList =
912           new ArrayList<String>(systemProperties.size());
913      for (final Map.Entry<String,String> e : systemProperties.entrySet())
914      {
915        propList.add(e.getKey() + "='" + e.getValue() + '\'');
916      }
917
918      addMonitorAttribute(attrs,
919           ATTR_SYSTEM_PROPERTY,
920           INFO_SYSTEM_INFO_DISPNAME_SYSTEM_PROP.get(),
921           INFO_SYSTEM_INFO_DESC_SYSTEM_PROP.get(),
922           propList);
923    }
924
925    return Collections.unmodifiableMap(attrs);
926  }
927}