/* |
|
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. |
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
* |
|
* This code is free software; you can redistribute it and/or modify it |
|
* under the terms of the GNU General Public License version 2 only, as |
|
* published by the Free Software Foundation. Oracle designates this |
|
* particular file as subject to the "Classpath" exception as provided |
|
* by Oracle in the LICENSE file that accompanied this code. |
|
* |
|
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
* version 2 for more details (a copy is included in the LICENSE file that |
|
* accompanied this code). |
|
* |
|
* You should have received a copy of the GNU General Public License version |
|
* 2 along with this work; if not, write to the Free Software Foundation, |
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
* |
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
* or visit www.oracle.com if you need additional information or have any |
|
* questions. |
|
*/ |
|
package sun.management; |
|
import java.io.IOException; |
|
import java.nio.ByteBuffer; |
|
import java.util.HashMap; |
|
import java.util.Iterator; |
|
import java.util.List; |
|
import java.util.Map; |
|
import java.util.concurrent.atomic.AtomicInteger; |
|
import sun.misc.Perf; |
|
import sun.management.counter.Units; |
|
import sun.management.counter.Counter; |
|
import sun.management.counter.perf.PerfInstrumentation; |
|
/** |
|
* A utility class to support the exporting and importing of the address |
|
* of a connector server using the instrumentation buffer. |
|
* |
|
* @since 1.5 |
|
*/ |
|
public class ConnectorAddressLink { |
|
private static final String CONNECTOR_ADDRESS_COUNTER = |
|
"sun.management.JMXConnectorServer.address"; |
|
/* |
|
* The format of the jvmstat counters representing the properties of |
|
* a given out-of-the-box JMX remote connector will be as follows: |
|
* |
|
* sun.management.JMXConnectorServer.<counter>.<key>=<value> |
|
* |
|
* where: |
|
* |
|
* counter = index computed by this class which uniquely identifies |
|
* an out-of-the-box JMX remote connector running in this |
|
* Java virtual machine. |
|
* key/value = a given key/value pair in the map supplied to the |
|
* exportRemote() method. |
|
* |
|
* For example, |
|
* |
|
* sun.management.JMXConnectorServer.0.remoteAddress=service:jmx:rmi:///jndi/rmi://myhost:5000/jmxrmi |
|
* sun.management.JMXConnectorServer.0.authenticate=false |
|
* sun.management.JMXConnectorServer.0.ssl=false |
|
* sun.management.JMXConnectorServer.0.sslRegistry=false |
|
* sun.management.JMXConnectorServer.0.sslNeedClientAuth=false |
|
*/ |
|
private static final String REMOTE_CONNECTOR_COUNTER_PREFIX = |
|
"sun.management.JMXConnectorServer."; |
|
/* |
|
* JMX remote connector counter (it will be incremented every |
|
* time a new out-of-the-box JMX remote connector is created). |
|
*/ |
|
private static AtomicInteger counter = new AtomicInteger(); |
|
/** |
|
* Exports the specified connector address to the instrumentation buffer |
|
* so that it can be read by this or other Java virtual machines running |
|
* on the same system. |
|
* |
|
* @param address The connector address. |
|
*/ |
|
public static void export(String address) { |
|
if (address == null || address.length() == 0) { |
|
throw new IllegalArgumentException("address not specified"); |
|
} |
|
Perf perf = Perf.getPerf(); |
|
perf.createString( |
|
CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address); |
|
} |
|
/** |
|
* Imports the connector address from the instrument buffer |
|
* of the specified Java virtual machine. |
|
* |
|
* @param vmid an identifier that uniquely identifies a local Java virtual |
|
* machine, or <code>0</code> to indicate the current Java virtual machine. |
|
* |
|
* @return the value of the connector address, or <code>null</code> if the |
|
* target VM has not exported a connector address. |
|
* |
|
* @throws IOException An I/O error occurred while trying to acquire the |
|
* instrumentation buffer. |
|
*/ |
|
public static String importFrom(int vmid) throws IOException { |
|
Perf perf = Perf.getPerf(); |
|
ByteBuffer bb; |
|
try { |
|
bb = perf.attach(vmid, "r"); |
|
} catch (IllegalArgumentException iae) { |
|
throw new IOException(iae.getMessage()); |
|
} |
|
List<Counter> counters = |
|
new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER); |
|
Iterator<Counter> i = counters.iterator(); |
|
if (i.hasNext()) { |
|
Counter c = i.next(); |
|
return (String) c.getValue(); |
|
} else { |
|
return null; |
|
} |
|
} |
|
/** |
|
* Exports the specified remote connector address and associated |
|
* configuration properties to the instrumentation buffer so that |
|
* it can be read by this or other Java virtual machines running |
|
* on the same system. |
|
* |
|
* @param properties The remote connector address properties. |
|
*/ |
|
public static void exportRemote(Map<String, String> properties) { |
|
final int index = counter.getAndIncrement(); |
|
Perf perf = Perf.getPerf(); |
|
for (Map.Entry<String, String> entry : properties.entrySet()) { |
|
perf.createString(REMOTE_CONNECTOR_COUNTER_PREFIX + index + "." + |
|
entry.getKey(), 1, Units.STRING.intValue(), entry.getValue()); |
|
} |
|
} |
|
/** |
|
* Imports the remote connector address and associated |
|
* configuration properties from the instrument buffer |
|
* of the specified Java virtual machine. |
|
* |
|
* @param vmid an identifier that uniquely identifies a local Java virtual |
|
* machine, or <code>0</code> to indicate the current Java virtual machine. |
|
* |
|
* @return a map containing the remote connector's properties, or an empty |
|
* map if the target VM has not exported the remote connector's properties. |
|
* |
|
* @throws IOException An I/O error occurred while trying to acquire the |
|
* instrumentation buffer. |
|
*/ |
|
public static Map<String, String> importRemoteFrom(int vmid) throws IOException { |
|
Perf perf = Perf.getPerf(); |
|
ByteBuffer bb; |
|
try { |
|
bb = perf.attach(vmid, "r"); |
|
} catch (IllegalArgumentException iae) { |
|
throw new IOException(iae.getMessage()); |
|
} |
|
List<Counter> counters = new PerfInstrumentation(bb).getAllCounters(); |
|
Map<String, String> properties = new HashMap<>(); |
|
for (Counter c : counters) { |
|
String name = c.getName(); |
|
if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) && |
|
!name.equals(CONNECTOR_ADDRESS_COUNTER)) { |
|
properties.put(name, c.getValue().toString()); |
|
} |
|
} |
|
return properties; |
|
} |
|
} |