提交 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;
......@@ -48,6 +49,37 @@ 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
......@@ -60,22 +92,22 @@ public class ConnectorAddressLink {
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,15 +179,17 @@ 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);
}
......@@ -175,7 +198,6 @@ public final class ConnectorBootstrap {
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());
}
......@@ -227,14 +251,14 @@ public final class ConnectorBootstrap {
private static Properties propertiesFromFile(String fname)
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;
......@@ -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,7 +344,7 @@ 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();
}
}
......@@ -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,14 +732,20 @@ 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
......@@ -714,7 +755,7 @@ public final class ConnectorBootstrap {
parameter, but that's quite a bit more verbose and pulls in
lots of knowledge of the RMI connector. */
return connServer;
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.
先完成此消息的编辑!
想要评论请 注册