1 /* 2 * Copyright (c) 2004, 2012, 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.management; 27 28 import java.io.IOException; 29 import java.nio.ByteBuffer; 30 import java.util.HashMap; 31 import java.util.Iterator; 32 import java.util.List; 33 import java.util.Map; 34 import java.util.concurrent.atomic.AtomicInteger; 35 36 import sun.misc.Perf; 37 import sun.management.counter.Units; 38 import sun.management.counter.Counter; 39 import sun.management.counter.perf.PerfInstrumentation; 40 41 /** 42 * A utility class to support the exporting and importing of the address 43 * of a connector server using the instrumentation buffer. 44 * 45 * @since 1.5 46 */ 47 public class ConnectorAddressLink { 48 49 private static final String CONNECTOR_ADDRESS_COUNTER = 50 "sun.management.JMXConnectorServer.address"; 51 52 /* 53 * The format of the jvmstat counters representing the properties of 54 * a given out-of-the-box JMX remote connector will be as follows: 55 * 56 * sun.management.JMXConnectorServer.<counter>.<key>=<value> 57 * 58 * where: 59 * 60 * counter = index computed by this class which uniquely identifies 61 * an out-of-the-box JMX remote connector running in this 62 * Java virtual machine. 63 * key/value = a given key/value pair in the map supplied to the 64 * exportRemote() method. 65 * 66 * For example, 67 * 68 * sun.management.JMXConnectorServer.0.remoteAddress=service:jmx:rmi:///jndi/rmi://myhost:5000/jmxrmi 69 * sun.management.JMXConnectorServer.0.authenticate=false 70 * sun.management.JMXConnectorServer.0.ssl=false 71 * sun.management.JMXConnectorServer.0.sslRegistry=false 72 * sun.management.JMXConnectorServer.0.sslNeedClientAuth=false 73 */ 74 private static final String REMOTE_CONNECTOR_COUNTER_PREFIX = 75 "sun.management.JMXConnectorServer."; 76 77 /* 78 * JMX remote connector counter (it will be incremented every 79 * time a new out-of-the-box JMX remote connector is created). 80 */ 81 private static AtomicInteger counter = new AtomicInteger(); 82 83 /** 84 * Exports the specified connector address to the instrumentation buffer 85 * so that it can be read by this or other Java virtual machines running 86 * on the same system. 87 * 88 * @param address The connector address. 89 */ export(String address)90 public static void export(String address) { 91 if (address == null || address.length() == 0) { 92 throw new IllegalArgumentException("address not specified"); 93 } 94 Perf perf = Perf.getPerf(); 95 perf.createString( 96 CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address); 97 } 98 99 /** 100 * Imports the connector address from the instrument buffer 101 * of the specified Java virtual machine. 102 * 103 * @param vmid an identifier that uniquely identifies a local Java virtual 104 * machine, or <code>0</code> to indicate the current Java virtual machine. 105 * 106 * @return the value of the connector address, or <code>null</code> if the 107 * target VM has not exported a connector address. 108 * 109 * @throws IOException An I/O error occurred while trying to acquire the 110 * instrumentation buffer. 111 */ importFrom(int vmid)112 public static String importFrom(int vmid) throws IOException { 113 Perf perf = Perf.getPerf(); 114 ByteBuffer bb; 115 try { 116 bb = perf.attach(vmid, "r"); 117 } catch (IllegalArgumentException iae) { 118 throw new IOException(iae.getMessage()); 119 } 120 List<Counter> counters = 121 new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER); 122 Iterator<Counter> i = counters.iterator(); 123 if (i.hasNext()) { 124 Counter c = i.next(); 125 return (String) c.getValue(); 126 } else { 127 return null; 128 } 129 } 130 131 /** 132 * Exports the specified remote connector address and associated 133 * configuration properties to the instrumentation buffer so that 134 * it can be read by this or other Java virtual machines running 135 * on the same system. 136 * 137 * @param properties The remote connector address properties. 138 */ exportRemote(Map<String, String> properties)139 public static void exportRemote(Map<String, String> properties) { 140 final int index = counter.getAndIncrement(); 141 Perf perf = Perf.getPerf(); 142 for (Map.Entry<String, String> entry : properties.entrySet()) { 143 perf.createString(REMOTE_CONNECTOR_COUNTER_PREFIX + index + "." + 144 entry.getKey(), 1, Units.STRING.intValue(), entry.getValue()); 145 } 146 } 147 148 /** 149 * Imports the remote connector address and associated 150 * configuration properties from the instrument buffer 151 * of the specified Java virtual machine. 152 * 153 * @param vmid an identifier that uniquely identifies a local Java virtual 154 * machine, or <code>0</code> to indicate the current Java virtual machine. 155 * 156 * @return a map containing the remote connector's properties, or an empty 157 * map if the target VM has not exported the remote connector's properties. 158 * 159 * @throws IOException An I/O error occurred while trying to acquire the 160 * instrumentation buffer. 161 */ importRemoteFrom(int vmid)162 public static Map<String, String> importRemoteFrom(int vmid) throws IOException { 163 Perf perf = Perf.getPerf(); 164 ByteBuffer bb; 165 try { 166 bb = perf.attach(vmid, "r"); 167 } catch (IllegalArgumentException iae) { 168 throw new IOException(iae.getMessage()); 169 } 170 List<Counter> counters = new PerfInstrumentation(bb).getAllCounters(); 171 Map<String, String> properties = new HashMap<>(); 172 for (Counter c : counters) { 173 String name = c.getName(); 174 if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) && 175 !name.equals(CONNECTOR_ADDRESS_COUNTER)) { 176 properties.put(name, c.getValue().toString()); 177 } 178 } 179 return properties; 180 } 181 } 182