mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
4981215: Publishing a port number for management console to access
Reviewed-by: emcmanus, dfuchs
This commit is contained in:
parent
f7ce4bc4ab
commit
f810300851
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
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;
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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. */
|
||||
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;
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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!");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user