提交 62acf0ec 编写于 作者: L lmalvent

4981215: Publishing a port number for management console to access

Reviewed-by: emcmanus, dfuchs
上级 5d53bf09
/*
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2004-2008 Sun Microsystems, Inc. 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
......@@ -25,12 +25,13 @@
package sun.management;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import sun.misc.Perf;
import sun.management.counter.Units;
......@@ -46,36 +47,67 @@ import sun.management.counter.perf.PerfInstrumentation;
public class ConnectorAddressLink {
private static final String CONNECTOR_ADDRESS_COUNTER =
"sun.management.JMXConnectorServer.address";
"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.
* @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);
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.
* @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.
* @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.
* @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();
......@@ -85,14 +117,65 @@ public class ConnectorAddressLink {
} catch (IllegalArgumentException iae) {
throw new IOException(iae.getMessage());
}
List counters = (new PerfInstrumentation(bb)).findByPattern(CONNECTOR_ADDRESS_COUNTER);
List counters =
new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER);
Iterator i = counters.iterator();
if (i.hasNext()) {
Counter c = (Counter)i.next();
return (String)c.getValue();
Counter c = (Counter) 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 counters = new PerfInstrumentation(bb).getAllCounters();
Map<String, String> properties = new HashMap<String, String>();
for (Object c : counters) {
String name = ((Counter) c).getName();
if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) &&
!name.equals(CONNECTOR_ADDRESS_COUNTER)) {
properties.put(name, ((Counter) c).getValue().toString());
}
}
return properties;
}
}
/*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-2008 Sun Microsystems, Inc. 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
......@@ -39,6 +39,7 @@ import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteObject;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
......@@ -70,12 +71,14 @@ import javax.rmi.ssl.SslRMIServerSocketFactory;
import javax.security.auth.Subject;
import sun.rmi.server.UnicastRef;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.server.UnicastServerRef2;
import sun.management.Agent;
import sun.management.AgentConfigurationError;
import static sun.management.AgentConfigurationError.*;
import sun.management.ConnectorAddressLink;
import sun.management.FileSystem;
import sun.management.snmp.util.MibLogger;
......@@ -92,20 +95,22 @@ public final class ConnectorBootstrap {
* Default values for JMX configuration properties.
**/
public static interface DefaultValues {
public static final String PORT="0";
public static final String CONFIG_FILE_NAME="management.properties";
public static final String USE_SSL="true";
public static final String USE_REGISTRY_SSL="false";
public static final String USE_AUTHENTICATION="true";
public static final String PASSWORD_FILE_NAME="jmxremote.password";
public static final String ACCESS_FILE_NAME="jmxremote.access";
public static final String SSL_NEED_CLIENT_AUTH="false";
public static final String PORT = "0";
public static final String CONFIG_FILE_NAME = "management.properties";
public static final String USE_SSL = "true";
public static final String USE_REGISTRY_SSL = "false";
public static final String USE_AUTHENTICATION = "true";
public static final String PASSWORD_FILE_NAME = "jmxremote.password";
public static final String ACCESS_FILE_NAME = "jmxremote.access";
public static final String SSL_NEED_CLIENT_AUTH = "false";
}
/**
* Names of JMX configuration properties.
**/
public static interface PropertyNames {
public static final String PORT =
"com.sun.management.jmxremote.port";
public static final String CONFIG_FILE_NAME =
......@@ -132,6 +137,21 @@ public final class ConnectorBootstrap {
"com.sun.management.jmxremote.ssl.config.file";
}
/**
* JMXConnectorServer associated data.
*/
private static class JMXConnectorServerData {
public JMXConnectorServerData(
JMXConnectorServer jmxConnectorServer,
JMXServiceURL jmxRemoteURL) {
this.jmxConnectorServer = jmxConnectorServer;
this.jmxRemoteURL = jmxRemoteURL;
}
JMXConnectorServer jmxConnectorServer;
JMXServiceURL jmxRemoteURL;
}
/**
* <p>Prevents our RMI server objects from keeping the JVM alive.</p>
*
......@@ -151,6 +171,7 @@ public final class ConnectorBootstrap {
* works). Hence the somewhat misleading name of this class.</p>
*/
private static class PermanentExporter implements RMIExporter {
public Remote exportObject(Remote obj,
int port,
RMIClientSocketFactory csf,
......@@ -158,24 +179,25 @@ public final class ConnectorBootstrap {
throws RemoteException {
synchronized (this) {
if (firstExported == null)
if (firstExported == null) {
firstExported = obj;
}
}
final UnicastServerRef ref;
if (csf == null && ssf == null)
if (csf == null && ssf == null) {
ref = new UnicastServerRef(port);
else
} else {
ref = new UnicastServerRef2(port, csf, ssf);
}
return ref.exportObject(obj, null, true);
}
// Nothing special to be done for this case
public boolean unexportObject(Remote obj, boolean force)
throws NoSuchObjectException {
throws NoSuchObjectException {
return UnicastRemoteObject.unexportObject(obj, force);
}
Remote firstExported;
}
......@@ -202,19 +224,21 @@ public final class ConnectorBootstrap {
}
private void checkAccessFileEntries(Subject subject) {
if (subject == null)
if (subject == null) {
throw new SecurityException(
"Access denied! No matching entries found in " +
"the access file [" + accessFile + "] as the " +
"authenticated Subject is null");
}
final Set principals = subject.getPrincipals();
for (Iterator i = principals.iterator(); i.hasNext(); ) {
for (Iterator i = principals.iterator(); i.hasNext();) {
final Principal p = (Principal) i.next();
if (properties.containsKey(p.getName()))
if (properties.containsKey(p.getName())) {
return;
}
}
final Set<String> principalsStr = new HashSet<String>();
for (Iterator i = principals.iterator(); i.hasNext(); ) {
for (Iterator i = principals.iterator(); i.hasNext();) {
final Principal p = (Principal) i.next();
principalsStr.add(p.getName());
}
......@@ -225,16 +249,16 @@ public final class ConnectorBootstrap {
}
private static Properties propertiesFromFile(String fname)
throws IOException {
throws IOException {
Properties p = new Properties();
if (fname == null)
if (fname == null) {
return p;
}
FileInputStream fin = new FileInputStream(fname);
p.load(fin);
fin.close();
return p;
}
private final Map<String, Object> environment;
private final Properties properties;
private final String accessFile;
......@@ -251,22 +275,23 @@ public final class ConnectorBootstrap {
// Load a new management properties
final Properties props = Agent.loadManagementProperties();
if (props == null) return null;
if (props == null) {
return null;
}
final String portStr = props.getProperty(PropertyNames.PORT);
// System.out.println("initializing: {port=" + portStr + ",
// properties="+props+"}");
return initialize(portStr,props);
return initialize(portStr, props);
}
/**
* Initializes and starts a JMX Connector Server for remote
* monitoring and management.
**/
public static synchronized
JMXConnectorServer initialize(String portStr, Properties props) {
public static synchronized JMXConnectorServer initialize(String portStr, Properties props) {
// Get port number
final int port;
......@@ -280,21 +305,21 @@ public final class ConnectorBootstrap {
}
// Do we use authentication?
final String useAuthenticationStr =
final String useAuthenticationStr =
props.getProperty(PropertyNames.USE_AUTHENTICATION,
DefaultValues.USE_AUTHENTICATION);
final boolean useAuthentication =
Boolean.valueOf(useAuthenticationStr).booleanValue();
// Do we use SSL?
final String useSslStr =
final String useSslStr =
props.getProperty(PropertyNames.USE_SSL,
DefaultValues.USE_SSL);
final boolean useSsl =
Boolean.valueOf(useSslStr).booleanValue();
// Do we use RMI Registry SSL?
final String useRegistrySslStr =
final String useRegistrySslStr =
props.getProperty(PropertyNames.USE_REGISTRY_SSL,
DefaultValues.USE_REGISTRY_SSL);
final boolean useRegistrySsl =
......@@ -307,7 +332,7 @@ public final class ConnectorBootstrap {
StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
int tokens = st.countTokens();
enabledCipherSuitesList = new String[tokens];
for (int i = 0 ; i < tokens; i++) {
for (int i = 0; i < tokens; i++) {
enabledCipherSuitesList[i] = st.nextToken();
}
}
......@@ -319,12 +344,12 @@ public final class ConnectorBootstrap {
StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
int tokens = st.countTokens();
enabledProtocolsList = new String[tokens];
for (int i = 0 ; i < tokens; i++) {
for (int i = 0; i < tokens; i++) {
enabledProtocolsList[i] = st.nextToken();
}
}
final String sslNeedClientAuthStr =
final String sslNeedClientAuthStr =
props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,
DefaultValues.SSL_NEED_CLIENT_AUTH);
final boolean sslNeedClientAuth =
......@@ -374,39 +399,49 @@ public final class ConnectorBootstrap {
sslNeedClientAuth +
"\n\t" + PropertyNames.USE_AUTHENTICATION + "=" +
useAuthentication +
(useAuthentication ?
(loginConfigName == null ?
("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
passwordFileName) :
("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
(useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
loginConfigName)) : "\n\t" +
Agent.getText("jmxremote.ConnectorBootstrap.initialize.noAuthentication")) +
(useAuthentication ?
("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
(useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
accessFileName) : "") +
"");
}
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXConnectorServer cs = null;
JMXServiceURL url = null;
try {
cs = exportMBeanServer(mbs, port, useSsl, useRegistrySsl,
final JMXConnectorServerData data = exportMBeanServer(
mbs, port, useSsl, useRegistrySsl,
sslConfigFileName, enabledCipherSuitesList,
enabledProtocolsList, sslNeedClientAuth,
useAuthentication, loginConfigName,
passwordFileName, accessFileName);
final JMXServiceURL url = cs.getAddress();
cs = data.jmxConnectorServer;
url = data.jmxRemoteURL;
log.config("initialize",
Agent.getText("jmxremote.ConnectorBootstrap.initialize.ready",
new JMXServiceURL(url.getProtocol(),
url.getHost(),
url.getPort(),
"/jndi/rmi://"+url.getHost()+":"+port+"/"+
"jmxrmi").toString()));
url.toString()));
} catch (Exception e) {
throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
}
try {
// Export remote connector address and associated configuration
// properties to the instrumentation buffer.
Map<String, String> properties = new HashMap<String, String>();
properties.put("remoteAddress", url.toString());
properties.put("authenticate", useAuthenticationStr);
properties.put("ssl", useSslStr);
properties.put("sslRegistry", useRegistrySslStr);
properties.put("sslNeedClientAuth", sslNeedClientAuthStr);
ConnectorAddressLink.exportRemote(properties);
} catch (Exception e) {
// Remote connector server started but unable to export remote
// connector address and associated configuration properties to
// the instrumentation buffer - non-fatal error.
log.debug("initialize", e);
}
return cs;
}
......@@ -452,7 +487,7 @@ public final class ConnectorBootstrap {
}
private static void checkPasswordFile(String passwordFileName) {
if (passwordFileName == null || passwordFileName.length()==0) {
if (passwordFileName == null || passwordFileName.length() == 0) {
throw new AgentConfigurationError(PASSWORD_FILE_NOT_SET);
}
File file = new File(passwordFileName);
......@@ -468,9 +503,9 @@ public final class ConnectorBootstrap {
try {
if (fs.supportsFileSecurity(file)) {
if (!fs.isAccessUserOnly(file)) {
final String msg=Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly",
final String msg = Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly",
passwordFileName);
log.config("initialize",msg);
log.config("initialize", msg);
throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED,
passwordFileName);
}
......@@ -482,7 +517,7 @@ public final class ConnectorBootstrap {
}
private static void checkAccessFile(String accessFileName) {
if (accessFileName == null || accessFileName.length()==0) {
if (accessFileName == null || accessFileName.length() == 0) {
throw new AgentConfigurationError(ACCESS_FILE_NOT_SET);
}
File file = new File(accessFileName);
......@@ -619,7 +654,7 @@ public final class ConnectorBootstrap {
}
}
private static JMXConnectorServer exportMBeanServer(
private static JMXConnectorServerData exportMBeanServer(
MBeanServer mbs,
int port,
boolean useSsl,
......@@ -697,24 +732,30 @@ public final class ConnectorBootstrap {
}
final Registry registry;
if (useRegistrySsl)
if (useRegistrySsl) {
registry =
new SingleEntryRegistry(port, csf, ssf,
"jmxrmi", exporter.firstExported);
else
} else {
registry =
new SingleEntryRegistry(port,
"jmxrmi", exporter.firstExported);
}
JMXServiceURL remoteURL = new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://" + url.getHost() + ":" +
((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort() +
"/jmxrmi");
/* Our exporter remembers the first object it was asked to
export, which will be an RMIServerImpl appropriate for
publication in our special registry. We could
alternatively have constructed the RMIServerImpl explicitly
and then constructed an RMIConnectorServer passing it as a
parameter, but that's quite a bit more verbose and pulls in
lots of knowledge of the RMI connector. */
return connServer;
export, which will be an RMIServerImpl appropriate for
publication in our special registry. We could
alternatively have constructed the RMIServerImpl explicitly
and then constructed an RMIConnectorServer passing it as a
parameter, but that's quite a bit more verbose and pulls in
lots of knowledge of the RMI connector. */
return new JMXConnectorServerData(connServer, remoteURL);
}
/**
......@@ -726,5 +767,4 @@ public final class ConnectorBootstrap {
// XXX Revisit: should probably clone this MibLogger....
private static final MibLogger log =
new MibLogger(ConnectorBootstrap.class);
}
/*
* Copyright 2008 Sun Microsystems, Inc. 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.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 4981215
* @summary Tests that the jvmstat counters published by the out-of-the-box
* management agent for the JMX connection details are correct.
* @author Luis-Miguel Alventosa
* @run clean JvmstatCountersTest
* @run build JvmstatCountersTest
* @run main/othervm JvmstatCountersTest 1
* @run main/othervm -Dcom.sun.management.jmxremote JvmstatCountersTest 2
* @run main/othervm -Dcom.sun.management.jmxremote.port=0 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false JvmstatCountersTest 3
* @run main/othervm JvmstatCountersTest 4
*/
import java.io.*;
import java.lang.management.*;
import java.util.*;
import javax.management.*;
import javax.management.remote.*;
import com.sun.tools.attach.*;
import sun.management.ConnectorAddressLink;
public class JvmstatCountersTest {
public static void checkAddress(String address) throws IOException {
System.out.println("Address = " + address);
JMXServiceURL url = new JMXServiceURL(address);
JMXConnector jmxc = JMXConnectorFactory.connect(url);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
System.out.println("MBean Count = " + mbsc.getMBeanCount());
}
public static void checkKey(Map<String, String> data, int index,
String key, String expectedValue) throws Exception {
String counter = "sun.management.JMXConnectorServer." + index + "." + key;
if (!data.containsKey(counter)) {
System.out.println("Test FAILED! Missing counter " + counter);
throw new IllegalArgumentException("Test case failed");
}
String value = data.get(counter);
if (key.equals("remoteAddress")) {
checkAddress(value);
} else if (!expectedValue.equals(value)) {
System.out.println("Test FAILED! Invalid counter " +
counter + "=" + value);
throw new IllegalArgumentException("Test case failed");
}
System.out.println("OK: " + counter + "=" + value);
}
public static void main(String args[]) throws Exception {
String localAddress = ConnectorAddressLink.importFrom(0);
Map<String, String> remoteData = ConnectorAddressLink.importRemoteFrom(0);
final int testCase = Integer.parseInt(args[0]);
switch (testCase) {
case 1:
if (localAddress == null && remoteData.isEmpty()) {
System.out.println("Test PASSED! The OOTB management " +
"agent didn't publish any jvmstat counter.");
} else {
System.out.println("Test FAILED! The OOTB management " +
"agent unexpectedly published jvmstat counters.");
throw new IllegalArgumentException("Test case 1 failed");
}
break;
case 2:
if (localAddress == null) {
System.out.println("Test FAILED! The OOTB management " +
"agent didn't publish the local connector.");
throw new IllegalArgumentException("Test case 2 failed");
}
checkAddress(localAddress);
if (!remoteData.isEmpty()) {
System.out.println("Test FAILED! The OOTB management " +
"agent shouldn't publish the remote connector.");
throw new IllegalArgumentException("Test case 2 failed");
}
System.out.println("Test PASSED! The OOTB management " +
"agent only publishes the local connector through " +
"a jvmstat counter.");
break;
case 3:
if (localAddress == null) {
System.out.println("Test FAILED! The OOTB management " +
"agent didn't publish the local connector.");
throw new IllegalArgumentException("Test case 3 failed");
}
checkAddress(localAddress);
if (remoteData.isEmpty()) {
System.out.println("Test FAILED! The OOTB management " +
"agent didnn't publish the remote connector.");
throw new IllegalArgumentException("Test case 3 failed");
}
for (String key : remoteData.keySet()) {
if (!key.startsWith("sun.management.JMXConnectorServer.0.")) {
System.out.println("Test FAILED! The OOTB management " +
"agent shouldn't publish anything which isn't " +
"related to the remote connector.");
throw new IllegalArgumentException("Test case 3 failed");
}
}
checkKey(remoteData, 0, "remoteAddress", null);
checkKey(remoteData, 0, "authenticate", "false");
checkKey(remoteData, 0, "ssl", "false");
checkKey(remoteData, 0, "sslRegistry", "false");
checkKey(remoteData, 0, "sslNeedClientAuth", "false");
System.out.println("Test PASSED! The OOTB management " +
"agent publishes both the local and remote " +
"connector info through jvmstat counters.");
break;
case 4:
if (localAddress != null || !remoteData.isEmpty()) {
System.out.println("Test FAILED! The OOTB management " +
"agent unexpectedly published jvmstat counters.");
throw new IllegalArgumentException("Test case 4 failed");
}
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
String name = rt.getName();
System.out.println("name = " + name);
String vmid = name.substring(0, name.indexOf("@"));
System.out.println("vmid = " + vmid);
VirtualMachine vm = VirtualMachine.attach(vmid);
String agent = vm.getSystemProperties().getProperty("java.home") +
File.separator + "lib" + File.separator + "management-agent.jar";
vm.loadAgent(agent, "com.sun.management.jmxremote.port=0,com.sun.management.jmxremote.authenticate=false,com.sun.management.jmxremote.ssl=false");
vm.detach();
String localAddress2 = ConnectorAddressLink.importFrom(0);
if (localAddress2 == null) {
System.out.println("Test FAILED! The OOTB management " +
"agent didn't publish the local connector.");
throw new IllegalArgumentException("Test case 4 failed");
}
checkAddress(localAddress2);
Map<String, String> remoteData2 = ConnectorAddressLink.importRemoteFrom(0);
if (remoteData2.isEmpty()) {
System.out.println("Test FAILED! The OOTB management " +
"agent didnn't publish the remote connector.");
throw new IllegalArgumentException("Test case 4 failed");
}
for (String key : remoteData2.keySet()) {
if (!key.startsWith("sun.management.JMXConnectorServer.0.")) {
System.out.println("Test FAILED! The OOTB management " +
"agent shouldn't publish anything which isn't " +
"related to the remote connector.");
throw new IllegalArgumentException("Test case 4 failed");
}
}
checkKey(remoteData2, 0, "remoteAddress", null);
checkKey(remoteData2, 0, "authenticate", "false");
checkKey(remoteData2, 0, "ssl", "false");
checkKey(remoteData2, 0, "sslRegistry", "false");
checkKey(remoteData2, 0, "sslNeedClientAuth", "false");
System.out.println("Test PASSED! The OOTB management agent " +
"publishes both the local and remote connector " +
"info through jvmstat counters when the agent is " +
"loaded through the Attach API.");
}
System.out.println("Bye! Bye!");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册