jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java
changeset 43592 14c12a5689d3
parent 43591 62824732af55
parent 43562 0cdf61c416d4
child 43593 06bce0388880
equal deleted inserted replaced
43591:62824732af55 43592:14c12a5689d3
     1 /*
       
     2  * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package sun.jvmstat.monitor;
       
    27 
       
    28 import java.net.URISyntaxException;
       
    29 import java.util.HashMap;
       
    30 import java.util.Map;
       
    31 import java.util.ServiceLoader;
       
    32 import java.util.Set;
       
    33 
       
    34 import sun.jvmstat.monitor.event.HostListener;
       
    35 
       
    36 /**
       
    37  * An abstraction for a host that contains instrumented Java Virtual
       
    38  * Machines. The class provides abstract factory methods for creating
       
    39  * concrete instances of this class and factory methods for creating
       
    40  * {@link MonitoredVm} instances. Concrete implementations of this class
       
    41  * provide methods for managing the communications protocols and provide
       
    42  * for event notification.
       
    43  *
       
    44  * @author Brian Doherty
       
    45  * @since 1.5
       
    46  *
       
    47  * @see HostIdentifier
       
    48  * @see VmIdentifier
       
    49  * @see MonitoredVm
       
    50  * @see HostListener
       
    51  */
       
    52 public abstract class MonitoredHost {
       
    53     private static Map<HostIdentifier, MonitoredHost> monitoredHosts =
       
    54                 new HashMap<HostIdentifier, MonitoredHost>();
       
    55 
       
    56     /*
       
    57      * The default optimized local protocol override mechanism. The value
       
    58      * of this property is used to construct the default package name
       
    59      * for the default optimized local protocol as follows:
       
    60      *        <IMPL_PACKAGE>.monitor.<LOCAL_PROTOCOL>
       
    61      * This property is not expected to be set under normal circumstances.
       
    62      */
       
    63     private static final String LOCAL_PROTOCOL_PROP_NAME =
       
    64             "sun.jvmstat.monitor.local";
       
    65     private static final String LOCAL_PROTOCOL =
       
    66             System.getProperty(LOCAL_PROTOCOL_PROP_NAME, "local");
       
    67 
       
    68     /*
       
    69      * The default remote protocol override mechanism. The value of
       
    70      * this property is used to construct the default package name
       
    71      * for the default remote protocol protocol as follows:
       
    72      *        <IMPL_PACKAGE>.monitor.protocol.<REMOTE_PROTOCOL>
       
    73      * This property is not expected to be set under normal circumstances.
       
    74      */
       
    75     private static final String REMOTE_PROTOCOL_PROP_NAME =
       
    76             "sun.jvmstat.monitor.remote";
       
    77     private static final String REMOTE_PROTOCOL =
       
    78             System.getProperty(REMOTE_PROTOCOL_PROP_NAME, "rmi");
       
    79 
       
    80     /**
       
    81      * The HostIdentifier for this MonitoredHost instance.
       
    82      */
       
    83     protected HostIdentifier hostId;
       
    84 
       
    85     /**
       
    86      * The polling interval, in milliseconds, for this MonitoredHost instance.
       
    87      */
       
    88     protected int interval;
       
    89 
       
    90     /**
       
    91      * The last Exception encountered while polling this MonitoredHost.
       
    92      */
       
    93     protected Exception lastException;
       
    94 
       
    95     /**
       
    96      * Factory method to construct MonitoredHost instances to manage
       
    97      * connections to the host indicated by {@code hostIdString}
       
    98      *
       
    99      * @param hostIdString a String representation of a {@link HostIdentifier}
       
   100      * @return MonitoredHost - the MonitoredHost instance for communicating
       
   101      *                         with the indicated host using the protocol
       
   102      *                         specified in hostIdString.
       
   103      * @throws MonitorException  Thrown if monitoring errors occur.
       
   104      * @throws URISyntaxException Thrown when the hostIdString is poorly
       
   105      *                            formed. This exception may get encapsulated
       
   106      *                            into MonitorException in a future revision.
       
   107      */
       
   108     public static MonitoredHost getMonitoredHost(String hostIdString)
       
   109                   throws MonitorException, URISyntaxException {
       
   110         HostIdentifier hostId = new HostIdentifier(hostIdString);
       
   111         return getMonitoredHost(hostId);
       
   112     }
       
   113 
       
   114     /**
       
   115      * Factory method to construct a MonitoredHost instance to manage the
       
   116      * connection to the Java Virtual Machine indicated by {@code vmid}.
       
   117      *
       
   118      * This method provide a convenient short cut for attaching to a specific
       
   119      * instrumented Java Virtual Machine. The information in the VmIdentifier
       
   120      * is used to construct a corresponding HostIdentifier, which in turn is
       
   121      * used to create the MonitoredHost instance.
       
   122      *
       
   123      * @param vmid The identifier for the target Java Virtual Machine.
       
   124      * @return MonitoredHost - The MonitoredHost object needed to attach to
       
   125      *                         the target Java Virtual Machine.
       
   126      *
       
   127      * @throws MonitorException Thrown if monitoring errors occur.
       
   128      */
       
   129     public static MonitoredHost getMonitoredHost(VmIdentifier vmid)
       
   130                  throws MonitorException {
       
   131         // use the VmIdentifier to construct the corresponding HostIdentifier
       
   132         HostIdentifier hostId = new HostIdentifier(vmid);
       
   133         return getMonitoredHost(hostId);
       
   134     }
       
   135 
       
   136 
       
   137     /*
       
   138      * Load the MonitoredHostServices
       
   139      */
       
   140     private static ServiceLoader<MonitoredHostService> monitoredHostServiceLoader =
       
   141         ServiceLoader.load(MonitoredHostService.class, MonitoredHostService.class.getClassLoader());
       
   142 
       
   143     /**
       
   144      * Factory method to construct a MonitoredHost instance to manage the
       
   145      * connection to the host indicated by {@code hostId}.
       
   146      *
       
   147      * @param hostId the identifier for the target host.
       
   148      * @return MonitoredHost - The MonitoredHost object needed to attach to
       
   149      *                         the target host.
       
   150      *
       
   151      * @throws MonitorException Thrown if monitoring errors occur.
       
   152      */
       
   153     public static MonitoredHost getMonitoredHost(HostIdentifier hostId)
       
   154                   throws MonitorException {
       
   155         MonitoredHost mh = null;
       
   156 
       
   157         synchronized(monitoredHosts) {
       
   158             mh = monitoredHosts.get(hostId);
       
   159             if (mh != null) {
       
   160                 if (mh.isErrored()) {
       
   161                     monitoredHosts.remove(hostId);
       
   162                 } else {
       
   163                     return mh;
       
   164                 }
       
   165             }
       
   166         }
       
   167 
       
   168         hostId = resolveHostId(hostId);
       
   169 
       
   170         for (MonitoredHostService mhs : monitoredHostServiceLoader) {
       
   171             if (mhs.getScheme().equals(hostId.getScheme())) {
       
   172                 mh = mhs.getMonitoredHost(hostId);
       
   173             }
       
   174         }
       
   175 
       
   176         if (mh == null) {
       
   177             throw new IllegalArgumentException("Could not find MonitoredHost for scheme: " + hostId.getScheme());
       
   178         }
       
   179 
       
   180         synchronized(monitoredHosts) {
       
   181             monitoredHosts.put(mh.hostId, mh);
       
   182         }
       
   183 
       
   184         return mh;
       
   185     }
       
   186 
       
   187     /**
       
   188      * Method to resolve unspecified components of the given HostIdentifier
       
   189      * by constructing a new HostIdentifier that replaces the unspecified
       
   190      * components with the default values.
       
   191      *
       
   192      * @param hostId the unresolved HostIdentifier.
       
   193      * @return HostIdentifier - a resolved HostIdentifier.
       
   194      *
       
   195      * @throws MonitorException Thrown if monitoring errors occur.
       
   196      */
       
   197     protected static HostIdentifier resolveHostId(HostIdentifier hostId)
       
   198                      throws MonitorException {
       
   199         String hostname = hostId.getHost();
       
   200         String scheme = hostId.getScheme();
       
   201         StringBuilder sb = new StringBuilder();
       
   202 
       
   203         assert hostname != null;
       
   204 
       
   205         if (scheme == null) {
       
   206             if (hostname.compareTo("localhost") == 0) {
       
   207                 scheme = LOCAL_PROTOCOL;
       
   208             } else {
       
   209                 scheme = REMOTE_PROTOCOL;
       
   210             }
       
   211         }
       
   212 
       
   213         sb.append(scheme).append(":").append(hostId.getSchemeSpecificPart());
       
   214 
       
   215         String frag = hostId.getFragment();
       
   216         if (frag != null) {
       
   217             sb.append("#").append(frag);
       
   218         }
       
   219 
       
   220         try {
       
   221             return new HostIdentifier(sb.toString());
       
   222         } catch (URISyntaxException e) {
       
   223             // programming error - HostIdentifier was valid.
       
   224             assert false;
       
   225             throw new IllegalArgumentException("Malformed URI created: "
       
   226                                                + sb.toString());
       
   227         }
       
   228     }
       
   229 
       
   230     /**
       
   231      * Return the resolved HostIdentifier for this MonitoredHost.
       
   232      *
       
   233      * @return HostIdentifier - the resolved HostIdentifier.
       
   234      */
       
   235     public HostIdentifier getHostIdentifier() {
       
   236         return hostId;
       
   237     }
       
   238 
       
   239     /* ---- Methods to support polled MonitoredHost Implementations ----- */
       
   240 
       
   241     /**
       
   242      * Set the polling interval for this MonitoredHost.
       
   243      *
       
   244      * @param interval the polling interval, in milliseconds
       
   245      */
       
   246     public void setInterval(int interval) {
       
   247         this.interval = interval;
       
   248     }
       
   249 
       
   250     /**
       
   251      * Get the polling interval.
       
   252      *
       
   253      * @return int - the polling interval in milliseconds for this MonitoredHost
       
   254      */
       
   255     public int getInterval() {
       
   256         return interval;
       
   257     }
       
   258 
       
   259     /**
       
   260      * Set the last exception encountered while polling this MonitoredHost.
       
   261      *
       
   262      * @param lastException the last exception encountered;
       
   263      */
       
   264     public void setLastException(Exception lastException) {
       
   265         this.lastException = lastException;
       
   266     }
       
   267 
       
   268     /**
       
   269      * Get the last exception encountered while polling this MonitoredHost.
       
   270      *
       
   271      * @return Exception - the last exception occurred while polling this
       
   272      *                     MonitoredHost, or {@code null} if no exception
       
   273      *                     has occurred or the exception has been cleared,
       
   274      */
       
   275     public Exception getLastException() {
       
   276         return lastException;
       
   277     }
       
   278 
       
   279     /**
       
   280      * Clear the last exception.
       
   281      */
       
   282     public void clearLastException() {
       
   283         lastException = null;
       
   284     }
       
   285 
       
   286     /**
       
   287      * Test if this MonitoredHost is in the errored state. If this method
       
   288      * returns true, then the Exception returned by getLastException()
       
   289      * indicates the Exception that caused the error condition.
       
   290      *
       
   291      * @return boolean - true if the MonitoredHost instance has experienced
       
   292      *                   an error, or false if it hasn't or if any past
       
   293      *                   error has been cleared.
       
   294      */
       
   295     public boolean isErrored() {
       
   296         return lastException != null;
       
   297     }
       
   298 
       
   299     /**
       
   300      * Get the MonitoredVm for the given Java Virtual Machine. The default
       
   301      * sampling interval is used for the MonitoredVm instance.
       
   302      *
       
   303      * @param id the VmIdentifier specifying the target Java Virtual Machine.
       
   304      * @return MonitoredVm - the MonitoredVm instance for the target Java
       
   305      *                       Virtual Machine.
       
   306      * @throws MonitorException Thrown if monitoring errors occur.
       
   307      */
       
   308     public abstract MonitoredVm getMonitoredVm(VmIdentifier id)
       
   309                                 throws MonitorException;
       
   310 
       
   311     /**
       
   312      * Get the MonitoredVm for the given Java Virtual Machine. The sampling
       
   313      * interval is set to the given interval.
       
   314      *
       
   315      * @param id the VmIdentifier specifying the target Java Virtual Machine.
       
   316      * @param interval the sampling interval for the target Java Virtual Machine.
       
   317      * @return MonitoredVm - the MonitoredVm instance for the target Java
       
   318      *                       Virtual Machine.
       
   319      * @throws MonitorException Thrown if monitoring errors occur.
       
   320      */
       
   321     public abstract MonitoredVm getMonitoredVm(VmIdentifier id, int interval)
       
   322                                 throws MonitorException;
       
   323 
       
   324     /**
       
   325      * Detach from the indicated MonitoredVm.
       
   326      *
       
   327      * @param vm the monitored Java Virtual Machine.
       
   328      * @throws MonitorException Thrown if monitoring errors occur.
       
   329      */
       
   330     public abstract void detach(MonitoredVm vm) throws MonitorException;
       
   331 
       
   332     /**
       
   333      * Add a HostListener. The given listener is added to the list
       
   334      * of HostListener objects to be notified of MonitoredHost related events.
       
   335      *
       
   336      * @param listener the HostListener to add.
       
   337      * @throws MonitorException Thrown if monitoring errors occur.
       
   338      */
       
   339     public abstract void addHostListener(HostListener listener)
       
   340                          throws MonitorException;
       
   341 
       
   342     /**
       
   343      * Remove a HostListener. The given listener is removed from the list
       
   344      * of HostListener objects to be notified of MonitoredHost related events.
       
   345      *
       
   346      * @param listener the HostListener to add.
       
   347      * @throws MonitorException Thrown if monitoring errors occur.
       
   348      */
       
   349     public abstract void removeHostListener(HostListener listener)
       
   350                          throws MonitorException;
       
   351 
       
   352     /**
       
   353      * Return the current set of active Java Virtual Machines for this
       
   354      * MonitoredHost. The returned Set contains {@link Integer} instances
       
   355      * holding the local virtual machine identifier, or <em>lvmid</em>
       
   356      * for each instrumented Java Virtual Machine currently available.
       
   357      *
       
   358      * @return Set - the current set of active Java Virtual Machines associated
       
   359      *               with this MonitoredHost, or the empty set of none.
       
   360      * @throws MonitorException Thrown if monitoring errors occur.
       
   361      */
       
   362     public abstract Set<Integer> activeVms() throws MonitorException;
       
   363 }