/* | 
|
 * 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;  | 
|
}  | 
|
}  |