JMX fixes for agentless configration

Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/6bc2410f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/6bc2410f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/6bc2410f

Branch: refs/heads/master
Commit: 6bc2410f592df048085ecbd28ee9920665e0d056
Parents: d2d78e4
Author: Andrew Kennedy <[email protected]>
Authored: Thu Aug 28 07:42:55 2014 +0100
Committer: Andrew Kennedy <[email protected]>
Committed: Sat Aug 30 17:23:47 2014 +0100

----------------------------------------------------------------------
 .../java/brooklyn/entity/java/JmxSupport.java   |  50 +++-----
 .../main/java/brooklyn/entity/java/UsesJmx.java | 116 +++++++++----------
 2 files changed, 74 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6bc2410f/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java 
b/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
index 19ee628..4ce9456 100644
--- a/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
+++ b/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
@@ -18,8 +18,6 @@
  */
 package brooklyn.entity.java;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import java.util.EnumSet;
 import java.util.List;
 
@@ -32,10 +30,8 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
 import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.effector.EffectorTasks;
 import brooklyn.event.feed.jmx.JmxHelper;
 import brooklyn.location.access.BrooklynAccessUtils;
 import brooklyn.location.basic.Locations;
@@ -160,24 +156,18 @@ public class JmxSupport implements UsesJmx {
 
     public String getJmxUrl() {
         init();
-        
-        String host = entity.getAttribute(Attributes.HOSTNAME);
-        if (host==null) {
-            SshMachineLocation machine = EffectorTasks.getSshMachine(entity);
-            host = machine.getAddress().getHostName();
-        }
-        
+
+        HostAndPort jmx = 
BrooklynAccessUtils.getBrooklynAccessibleAddress(entity, 
entity.getAttribute(JMX_PORT));
+        HostAndPort rmi = 
BrooklynAccessUtils.getBrooklynAccessibleAddress(entity, 
entity.getAttribute(RMI_REGISTRY_PORT));
+
         if (EnumSet.of(JmxAgentModes.JMXMP, 
JmxAgentModes.JMXMP_AND_RMI).contains(getJmxAgentMode())) {
-            HostAndPort jmxmp = 
BrooklynAccessUtils.getBrooklynAccessibleAddress(entity, 
entity.getAttribute(JMX_PORT));
-            return JmxHelper.toJmxmpUrl(jmxmp.getHostText(), jmxmp.getPort());
+            return JmxHelper.toJmxmpUrl(jmx.getHostText(), jmx.getPort());
         } else {
             if (getJmxAgentMode() == JmxAgentModes.NONE) {
                 fixPortsForModeNone();
             }
             // this will work for agent or agentless
-            return JmxHelper.toRmiJmxUrl(host,
-                    entity.getAttribute(JMX_PORT),
-                    entity.getAttribute(RMI_REGISTRY_PORT),
+            return JmxHelper.toRmiJmxUrl(jmx.getHostText(), jmx.getPort(), 
rmi.getPort(),
                     entity.getAttribute(JMX_CONTEXT));
         }
     }
@@ -269,18 +259,18 @@ public class JmxSupport implements UsesJmx {
     /** applies _some_ of the common settings needed to connect via JMX */
     public void applyJmxJavaSystemProperties(MutableMap.Builder<String,Object> 
result) {
         if (!isJmx()) return ;
-        
-        Integer jmxRemotePort;
-        String hostName = getEntity().getAttribute(Attributes.HOSTNAME);
-        if (hostName==null) hostName = 
checkNotNull(getMachine().get().getAddress().getHostName(), "hostname for 
entity " + entity);
-        
+
+        HostAndPort jmx = 
BrooklynAccessUtils.getBrooklynAccessibleAddress(entity, 
entity.getAttribute(JMX_PORT));
+        Integer jmxRemotePort = getEntity().getAttribute(JMX_PORT);
+        String hostName = jmx.getHostText();
+
         result.put("com.sun.management.jmxremote", null);
+        result.put("java.rmi.server.hostname", hostName);
 
         switch (getJmxAgentMode()) {
         case JMXMP_AND_RMI:
             result.put(JmxmpAgent.RMI_REGISTRY_PORT_PROPERTY, 
Preconditions.checkNotNull(entity.getAttribute(UsesJmx.RMI_REGISTRY_PORT), 
"registry port"));
         case JMXMP:
-            jmxRemotePort = getEntity().getAttribute(JMX_PORT);
             if (jmxRemotePort==null || jmxRemotePort<=0)
                 throw new IllegalStateException("Unsupported JMX port 
"+jmxRemotePort+" - when applying system properties ("+getJmxAgentMode()+" / 
"+getEntity()+")");
             result.put(JmxmpAgent.JMXMP_PORT_PROPERTY, jmxRemotePort);
@@ -289,25 +279,21 @@ public class JmxSupport implements UsesJmx {
             // (should not be present, but remove just to be sure)
             result.remove("java.rmi.server.hostname");
             break;
-        case JMX_RMI_CUSTOM_AGENT:    
-            jmxRemotePort = getEntity().getAttribute(JMX_PORT);
+        case JMX_RMI_CUSTOM_AGENT:
             if (jmxRemotePort==null || jmxRemotePort<=0)
                 throw new IllegalStateException("Unsupported JMX port 
"+jmxRemotePort+" - when applying system properties ("+getJmxAgentMode()+" / 
"+getEntity()+")");
-            result.put(JmxRmiAgent.RMI_REGISTRY_PORT_PROPERTY, 
-                    
Preconditions.checkNotNull(entity.getAttribute(UsesJmx.RMI_REGISTRY_PORT), 
"registry port"));
+            result.put(JmxRmiAgent.RMI_REGISTRY_PORT_PROPERTY, 
Preconditions.checkNotNull(entity.getAttribute(UsesJmx.RMI_REGISTRY_PORT), 
"registry port"));
             result.put(JmxRmiAgent.JMX_SERVER_PORT_PROPERTY, jmxRemotePort);
-            result.put("java.rmi.server.hostname", hostName);
             break;
         case NONE:
-            // only for mode 'NONE' - other modes use different fields
             jmxRemotePort = fixPortsForModeNone();
+        case JMX_RMI:
             result.put("com.sun.management.jmxremote.port", jmxRemotePort);
-            result.put("java.rmi.server.hostname", hostName);
             break;
-        default:    
+        default:
             throw new IllegalStateException("Unsupported JMX mode - when 
applying system properties ("+getJmxAgentMode()+" / "+getEntity()+")");
         }
-        
+
         if (isSecure()) {
             // set values true, and apply keys pointing to keystore / 
truststore
             getJmxSslSupport().applyAgentJmxJavaSystemProperties(result);
@@ -320,7 +306,7 @@ public class JmxSupport implements UsesJmx {
 
     /** installs files needed for JMX, to the runDir given in constructor, 
assuming the runDir has been created */ 
     public void install() {
-        if (getJmxAgentMode()!=JmxAgentModes.NONE) {
+        if (EnumSet.of(JmxAgentModes.JMXMP_AND_RMI, JmxAgentModes.JMXMP, 
JmxAgentModes.JMX_RMI_CUSTOM_AGENT).contains(getJmxAgentMode())) {
             
getMachine().get().copyTo(ResourceUtils.create(this).getResourceFromUrl(
                 getJmxAgentJarUrl()), getJmxAgentJarDestinationFilePath());
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6bc2410f/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java 
b/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
index 8166d0c..ff8164a 100644
--- a/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
+++ b/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
@@ -25,6 +25,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
@@ -34,14 +35,14 @@ import brooklyn.util.flags.SetFromFlag;
 
 public interface UsesJmx extends UsesJava {
 
-    public static final int DEFAULT_JMX_PORT = 1099;   // RMI port?
+    public static final int DEFAULT_JMX_PORT = 1099; // RMI port?
 
     @SetFromFlag("useJmx")
-    public static final ConfigKey<Boolean> USE_JMX = 
ConfigKeys.newConfigKey("jmx.enabled", "JMX enabled", Boolean.TRUE);
+    ConfigKey<Boolean> USE_JMX = ConfigKeys.newConfigKey("jmx.enabled", "JMX 
enabled", Boolean.TRUE);
 
-    /** chosen by java itself by default; setting this will only have any 
effect if using an agent */ 
+    /** Chosen by Java itself by default, setting this will only have any 
effect if using an agent. */
     @SetFromFlag("jmxPort")
-    public static final PortAttributeSensorAndConfigKey JMX_PORT = new 
PortAttributeSensorAndConfigKey(
+    PortAttributeSensorAndConfigKey JMX_PORT = new 
PortAttributeSensorAndConfigKey(
             "jmx.direct.port", "JMX direct/private port (e.g. JMX RMI server 
port, or JMXMP port, but not RMI registry port)", 
PortRanges.fromString("31001+")) {
         @Override protected Integer convertConfigToSensor(PortRange value, 
Entity entity) {
             // TODO when using JmxAgentModes.NONE we should *not* convert, but 
leave it null
@@ -52,64 +53,59 @@ public interface UsesJmx extends UsesJava {
             return super.convertConfigToSensor(value, entity);
         }
     };
-    
-    /** well-known port used by Java itself to start the RMI registry where 
JMX private port can be discovered;
-     * ignored if using JMXMP agent
-     */ 
+
+    /** Well-known port used by Java itself to start the RMI registry where 
JMX private port can be discovered, ignored if using JMXMP agent. */
     @SetFromFlag("rmiRegistryPort")
-    public static final PortAttributeSensorAndConfigKey RMI_REGISTRY_PORT = 
new PortAttributeSensorAndConfigKey(
-            "rmi.registry.port", "RMI registry port, used for discovering JMX 
(private) port", PortRanges.fromString("1099, 19099+"));
+    PortAttributeSensorAndConfigKey RMI_REGISTRY_PORT = 
ConfigKeys.newPortSensorAndConfigKey(
+            "rmi.registry.port", "RMI registry port, used for discovering JMX 
(private) port", PortRanges.fromString("1099,19099+"));
 
     @SetFromFlag("jmxContext")
-    public static final BasicAttributeSensorAndConfigKey<String> JMX_CONTEXT = 
new BasicAttributeSensorAndConfigKey<String>(
-            String.class, "jmx.context", "JMX context path", "jmxrmi");
+    AttributeSensorAndConfigKey<String, String> JMX_CONTEXT = 
ConfigKeys.newStringSensorAndConfigKey("jmx.context", "JMX context path", 
"jmxrmi");
 
-    public static final AttributeSensor<String> JMX_URL = new 
BasicAttributeSensorAndConfigKey<String>(
+    AttributeSensor<String> JMX_URL = new 
BasicAttributeSensorAndConfigKey<String>(
             String.class, "jmx.service.url", "The URL for connecting to the 
MBean Server");
 
-    /** forces JMX to be secured, using JMXMP so it gets through firewalls 
_and_ SSL/TLS
-     * (NB: there is not currently any corresponding JMXMP without SSL/TLS) */
+    /** Forces JMX to be secured, using JMXMP so it gets through firewalls 
<em>and</em> SSL/TLS. */
     @SetFromFlag("jmxSecure")
-    public static final ConfigKey<Boolean> JMX_SSL_ENABLED = 
ConfigKeys.newBooleanConfigKey("jmx.ssl.enabled", "JMX over JMXMP enabled with 
SSL/TLS", Boolean.FALSE);
+    ConfigKey<Boolean> JMX_SSL_ENABLED = 
ConfigKeys.newBooleanConfigKey("jmx.ssl.enabled", "JMX over JMXMP enabled with 
SSL/TLS", Boolean.FALSE);
 
-    public enum JmxAgentModes {
-        /** auto-detect the agent to use based on location, preferring JMXMP 
except at localhost where JMX_RMI_CUSTOM_AGENT is preferred */
+    enum JmxAgentModes {
+        /** Auto-detect the agent to use based on location. Prefer {@link 
#JMXMP} except at localhost which uses {@link #JMX_RMI_CUSTOM_AGENT}. */
         AUTODETECT,
-        /** JMXMP which permits firewall access through a single port {@link 
UsesJmx#JMX_PORT} */
+
+        /** JMXMP which permits firewall access through a single port {@link 
UsesJmx#JMX_PORT}. */
         JMXMP,
-        /** Start {@link #JMXMP} along with an RMI Registry on {@link 
UsesJmx#RMI_REGISTRY_PORT}
-         * (redirecting to an anonymous high-numbered port as the RMI server) 
*/
+
+        /** Start {@link #JMXMP} along with an RMI Registry on {@link 
UsesJmx#RMI_REGISTRY_PORT}, redirecting to an anonymous high-numbered port as 
the RMI server. */
         JMXMP_AND_RMI,
-        /** JMX over RMI custom agent which permits access through a known RMI 
registry port, redirected to a known JMX-RMI port;
-         * two ports must be opened on the firewall, and the same hostname 
resolvable on the target machine and by the client */
+
+        /** JMX over RMI custom agent which permits access through a known 
{@link UsesJmx#RMI_REGISTRY_PORT}, redirected to a known {@link 
UsesJmx#JMX_PORT}.
+         * Both ports must be opened on the firewall, and the same hostname 
resolvable on the target machine and by the client */
         JMX_RMI_CUSTOM_AGENT,
-        /** do not install a JMX agent; use the default RMI which opens a 
registry at a known port, redirected to an _unknown_ port for jmx 
-         * (experimental) */
+
+        /** As with {@link UsesJmx#JMX_RMI_CUSTOM_AGENT} but no custom agent 
requred, entity must handle pots correctly.  */
+        JMX_RMI,
+
+        /** Do not install a JMX agent. Use the default {@link 
UsesJmx#RMI_REGISTRY_PORT}, redirected to an unknown port for JMX. */
         NONE
     }
-    
+
     @SetFromFlag("jmxAgentMode")
-    public static final ConfigKey<JmxAgentModes> JMX_AGENT_MODE = 
ConfigKeys.newConfigKey(JmxAgentModes.class,
-            "jmx.agent.mode", "What type of JMX agent to use; defaults to null 
(autodetect) which means " +
-               "JMXMP_AND_RMI allowing firewall access through a single port 
as well as local access supporting jconsole " +
-               "(unless JMX_SSL_ENABLED is set, in which case it is JMXMP 
only)", 
-               JmxAgentModes.AUTODETECT);
+    ConfigKey<JmxAgentModes> JMX_AGENT_MODE = 
ConfigKeys.newConfigKey("jmx.agent.mode",
+            "What type of JMX agent to use; defaults to null (autodetect) 
which means " +
+            "JMXMP_AND_RMI allowing firewall access through a single port as 
well as local access supporting jconsole " +
+            "(unless JMX_SSL_ENABLED is set, in which case it is JMXMP only)",
+            JmxAgentModes.AUTODETECT);
+
+    /* Currently these are only used to connect, so only applies where systems 
set this up themselves. */
+    AttributeSensorAndConfigKey<String, String> JMX_USER = 
ConfigKeys.newStringSensorAndConfigKey("jmx.user", "JMX username");
+    AttributeSensorAndConfigKey<String, String> JMX_PASSWORD = 
ConfigKeys.newStringSensorAndConfigKey("jmx.password", "JMX password");
 
-    /** Currently only used to connect; not used to set up JMX (so only 
applies where systems set this up themselves)
-     */
-    public static final BasicAttributeSensorAndConfigKey<String> JMX_USER = 
new BasicAttributeSensorAndConfigKey<String>(
-            String.class, "jmx.user", "JMX username");
-    
-    /** Currently only used to connect; not used to set up JMX (so only 
applies where systems set this up themselves)
-     */
-    public static final BasicAttributeSensorAndConfigKey<String> JMX_PASSWORD 
= new BasicAttributeSensorAndConfigKey<String>(
-            String.class, "jmx.password", "JMX password");
-    
     /*
      * Synopsis of how the keys work for JMX_SSL:
-     * 
+     *
      * BROOKLYN
-     *  * brooklyn ROOT key + cert -> 
+     *  * brooklyn ROOT key + cert ->
      *      used to identify things brooklyn has signed, ie to confirm their 
identity
      *      signs all certs created by brooklyn
      *      (created per entity if not specified as input)
@@ -120,7 +116,7 @@ public interface UsesJmx extends UsesJava {
      *      global would probably be fine but more work;
      *      however it is important that this _not_ sign agents keys,
      *      to prevent agents from accessing other agents)
-     * 
+     *
      * AGENT (e.g. JMX server in each managed java process)
      *  * gets AGENT key + cert ->
      *      signed by brooklyn ROOT, used to authenticate itself to brooklyn
@@ -129,57 +125,57 @@ public interface UsesJmx extends UsesJava {
      */
 
     /* TODO brooklyn ROOT key
-     *  
+     *
     public static final ConfigKey<String> BROOKLYN_SSL_ROOT_KEYSTORE_URL = new 
BasicConfigKey<String>(
             String.class, "brooklyn.ssl.root.keyStoreUrl", "URL to keystore 
Brooklyn should use as root private key and certificate-signing authority", 
null);
-    
+
     public static final ConfigKey<String> BROOKLYN_SSL_ROOT_KEY_DATA = new 
BasicConfigKey<String>(
             String.class, "brooklyn.ssl.root.key", "root private key (RSA 
string format), used to sign managed servers", null);
     public static final ConfigKey<String> BROOKLYN_SSL_ROOT_CERT_DATA = new 
BasicConfigKey<String>(
             String.class, "brooklyn.ssl.root.cert", "certificate for root 
private key (RSA string format)", null);
-    
+
      * brooklyn.ssl.root.keyStorePassword
      * brooklyn.ssl.root.keyAlias (if null, looks for one called 'brooklyn', 
otherwise takes the first key)
      * brooklyn.ssl.root.keyPassword
-     */ 
-    
+     */
+
     public static final ConfigKey<PrivateKey> JMX_SSL_ACCESS_KEY = new 
BasicConfigKey<PrivateKey>(
             PrivateKey.class, "jmx.ssl.access.key", "key used to access a JMX 
agent (typically per entity, embedded in the managed JVM)", null);
     public static final ConfigKey<Certificate> JMX_SSL_ACCESS_CERT = new 
BasicConfigKey<Certificate>(
             Certificate.class, "jmx.ssl.access.cert", "certificate of key used 
to access a JMX agent", null);
-    
+
     /* TODO specify a keystore from which to get the access key
      * (above keys are set programmatically, typically _not_ by the user ... 
keystore would be the way to do that)
-     * 
+     *
      * jmx.ssl.access.keyStoreUrl (optional)
      * jmx.ssl.access.keyStorePassword (optional)
      * jmx.ssl.access.keyAlias (optional)
      */
-    
+
     /* could allow user to specify additional certs for JMX agents which 
should be trusted
-     *    
+     *
      * jmx.ssl.access.trustStoreUrl
      */
-    
-    /* optionally: could allow JMX agent to trust additional accessers, 
+
+    /* optionally: could allow JMX agent to trust additional accessers,
      * and/or use known keys in the case that other accessers might want to 
authenticate the JMX server
-     *   
-     * NB currently agent keys are not stored in brooklyn... no reason to as 
+     *
+     * NB currently agent keys are not stored in brooklyn... no reason to as
      * (a) currently we trust jmx agents; and (b) for agent-auth we should 
simply sign keys;
      * either way, seems fine for brooklyn to throw them away once they are 
installed on the remote machine)
-     * 
+     *
      * jmx.ssl.agent.keyStoreUrl
      * jmx.ssl.agent.keyStorePassword
      * jmx.ssl.agent.keyAlias
      * jmx.ssl.agent.keyPassword
-     * 
+     *
      * jmx.ssl.agent.trustStoreUrl
      */
 
     /* optionally: this could be set to disallow attaching to JMX through the 
attach mechanism
      * (but this option is generally not considered needed, as JVM attachment 
is
      * already restricted to localhost and to the the user running the process)
-     * 
+     *
      * -XX:+DisableAttachMechanism
      */
 }
\ No newline at end of file

Reply via email to