| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.brooklyn.entity.java; |
| |
| import java.security.PrivateKey; |
| import java.security.cert.Certificate; |
| |
| import org.apache.brooklyn.api.entity.Entity; |
| import org.apache.brooklyn.api.location.PortRange; |
| import org.apache.brooklyn.api.sensor.AttributeSensor; |
| import org.apache.brooklyn.config.ConfigKey; |
| import org.apache.brooklyn.core.config.BasicConfigKey; |
| import org.apache.brooklyn.core.config.ConfigKeys; |
| import org.apache.brooklyn.core.location.PortRanges; |
| import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey; |
| import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey; |
| import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey; |
| import org.apache.brooklyn.util.core.flags.SetFromFlag; |
| |
| public interface UsesJmx extends UsesJava { |
| |
| public static final int DEFAULT_JMX_PORT = 1099; // RMI port? |
| |
| @SetFromFlag("useJmx") |
| 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. */ |
| @SetFromFlag("jmxPort") |
| 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+")); |
| |
| // Default is deliberately null for this unused config; if we used "31001+" then we'd potentially give this sensor |
| // the value 31001 and jmx.direct.port the value 31002. See https://issues.apache.org/jira/browse/BROOKLYN-98 |
| /** @deprecated since 0.7.0, kept for rebinding with the anonymous class; code should only ever use {@link #JMX_PORT} */ @Deprecated |
| PortAttributeSensorAndConfigKey JMX_PORT_LEGACY = new PortAttributeSensorAndConfigKey( |
| "jmx.direct.port.legacy.NOT_USED", "Legacy definition JMX direct/private port (e.g. JMX RMI server port, or JMXMP port, but not RMI registry port)", null) { |
| private static final long serialVersionUID = 3846846080809179437L; |
| @Override protected Integer convertConfigToSensor(PortRange value, Entity entity) { |
| // TODO when using JmxAgentModes.NONE we should *not* convert, but leave it null |
| // (e.g. to prevent a warning in e.g. ActiveMQIntegrationTest) |
| // [there was - previously - a note about needing to move these keys to UsesJmx, |
| // that has been done, so not sure if there is anything more needed or if we can just |
| // check here entity.getConfig(JMX_AGENT_MODE) ... needs testing of course] |
| 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. */ |
| @SetFromFlag("rmiRegistryPort") |
| PortAttributeSensorAndConfigKey RMI_REGISTRY_PORT = ConfigKeys.newPortSensorAndConfigKey( |
| "rmi.registry.port", "RMI registry port, used for discovering JMX (private) port", PortRanges.fromString("1099,19099+")); |
| |
| @SetFromFlag("jmxContext") |
| AttributeSensorAndConfigKey<String, String> JMX_CONTEXT = ConfigKeys.newStringSensorAndConfigKey("jmx.context", "JMX context path", "jmxrmi"); |
| |
| 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 <em>and</em> SSL/TLS. */ |
| @SetFromFlag("jmxSecure") |
| ConfigKey<Boolean> JMX_SSL_ENABLED = ConfigKeys.newBooleanConfigKey("jmx.ssl.enabled", "JMX over JMXMP enabled with SSL/TLS", Boolean.FALSE); |
| |
| 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, |
| |
| /** 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 {@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, |
| |
| /** 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") |
| 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"); |
| |
| AttributeSensorAndConfigKey<String, String> JMX_AGENT_LOCAL_PATH = ConfigKeys.newStringSensorAndConfigKey("jmx.agent.local.path", "Path to JMX driver on the local machine"); |
| |
| /* |
| * Synopsis of how the keys work for JMX_SSL: |
| * |
| * BROOKLYN |
| * * 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) |
| * * brooklyn JMX ACCESS key + cert -> |
| * used to authenticate brooklyn to remote JMX agent |
| * typically, but not necessarily, signed by ROOT cert |
| * (typically created per entity, unless specified; |
| * 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 |
| * (brooklyn trusts this; does not need to remember this) |
| * * trusts only the relevant brooklyn JMX ACCESS key (its truststore contains that cert) |
| */ |
| |
| /* 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, |
| * 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 |
| * (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 |
| */ |
| } |