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