Author: mircea.markus
Date: 2009-03-10 17:24:47 -0400 (Tue, 10 Mar 2009)
New Revision: 7896
Added:
core/branches/flat/src/test/java/org/horizon/jmx/
core/branches/flat/src/test/java/org/horizon/jmx/JmxRegistrationManagerTest.java
core/branches/flat/src/test/java/org/horizon/jmx/ResourceDMBeanTest.java
Modified:
core/branches/flat/src/main/java/org/horizon/config/Configuration.java
core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java
core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java
core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd
core/branches/flat/src/test/java/org/horizon/config/parsing/XmlFileParsingTest.java
core/branches/flat/src/test/resources/configs/named-cache-test.xml
Log:
ongoing JMX integration
Modified: core/branches/flat/src/main/java/org/horizon/config/Configuration.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/Configuration.java 2009-03-10
10:56:24 UTC (rev 7895)
+++ core/branches/flat/src/main/java/org/horizon/config/Configuration.java 2009-03-10
21:24:47 UTC (rev 7896)
@@ -43,6 +43,7 @@
// reference to a global configuration
private GlobalConfiguration globalConfiguration;
+ private String JmxNameBase;
public GlobalConfiguration getGlobalConfiguration() {
@@ -63,6 +64,25 @@
}
/**
+ * If JMX statistics are enabled then all 'published' JMX objects will appear
under this name. This is optional, if
+ * not specified an object name will be created for you by default.
+ *
+ * @see javax.management.ObjectName
+ * @see #isExposeManagementStatistics()
+ */
+ public void setJmxNameBase(String jmxObjectName) {
+ testImmutability("JmxNameBase");
+ this.JmxNameBase = jmxObjectName;
+ }
+
+ /**
+ * @see #setJmxNameBase(String)
+ */
+ public String getJmxNameBase() {
+ return JmxNameBase;
+ }
+
+ /**
* Cache replication mode.
*/
public static enum CacheMode {
Modified:
core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
===================================================================
---
core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java 2009-03-10
10:56:24 UTC (rev 7895)
+++
core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java 2009-03-10
21:24:47 UTC (rev 7896)
@@ -291,6 +291,10 @@
// by default enable this since the element is present!
config.setExposeManagementStatistics(true);
}
+ String jmxNameBase = getAttributeValue(element, "jmxNameBase");
+ if (existsAttribute(jmxNameBase)) {
+ config.setJmxNameBase(jmxNameBase);
+ }
}
}
Modified: core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java
===================================================================
---
core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java 2009-03-10
10:56:24 UTC (rev 7895)
+++
core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java 2009-03-10
21:24:47 UTC (rev 7896)
@@ -23,13 +23,12 @@
import org.horizon.AdvancedCache;
import org.horizon.CacheException;
-import org.horizon.config.Configuration;
import org.horizon.factories.ComponentRegistry;
import org.horizon.logging.Log;
import org.horizon.logging.LogFactory;
+import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
@@ -53,28 +52,13 @@
private static final Log log = LogFactory.getLog(JmxRegistrationManager.class);
- private static final String GENERAL_PREFIX =
System.getProperty("horizon.jmx.prefix", "horizon:service=Horizon");
-
- /**
- * default ObjectName for clusterd caches. Cluster name should pe appended.
- */
- public static final String REPLICATED_CACHE_PREFIX = GENERAL_PREFIX +
",cluster=";
-
- /**
- * default ObjectName for non clustered caches. An unique identifier should be
appended.
- */
- public static final String LOCAL_CACHE_PREFIX = GENERAL_PREFIX +
",uniqueId=";
-
- /**
- * Key for every Dynamic mbean added.
- */
- public static final String JMX_RESOURCE_KEY = ",jmx-resource=";
-
private MBeanServer mBeanServer;
private String objectNameBase;
private AdvancedCache cache;
+ public static final String CACHE_NAME_KEY = "cache-name";
+ public static final String JMX_RESOURCE_KEY = "jmx-resource";
/**
* C-tor.
@@ -83,39 +67,21 @@
* @param cache cache that needs to be monitored
* @param objectNameBase path in the MBeanServer where to register cache MBeans
*/
- public JmxRegistrationManager(MBeanServer mBeanServer, AdvancedCache cache, ObjectName
objectNameBase) {
+ public JmxRegistrationManager(MBeanServer mBeanServer, AdvancedCache cache) {
this.mBeanServer = mBeanServer;
this.cache = cache;
- processBaseName(objectNameBase);
+ processBaseName();
}
/**
- * @throws IllegalArgumentException if the supplied objectNameBase name isn't
valid
- */
- public JmxRegistrationManager(MBeanServer mBeanServer, AdvancedCache cache, String
objectNameBase) {
- this.mBeanServer = mBeanServer;
- this.cache = cache;
- try {
- processBaseName(new ObjectName(objectNameBase));
- }
- catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException("Invalid Object Name : " +
objectNameBase, e);
- }
- }
-
- /**
* Defaults to platform to platform MBeanServer.
*
* @see java.lang.management.ManagementFactory#getPlatformMBeanServer()
* @see <a
href="http://java.sun.com/j2se/1.5.0/docs/guide/management/mxbeans.h...
* MBeanServer</a>
*/
- public JmxRegistrationManager(AdvancedCache cache, ObjectName objectNameBase) {
- this(ManagementFactory.getPlatformMBeanServer(), cache, objectNameBase);
- }
-
public JmxRegistrationManager(AdvancedCache cache) {
- this(cache, null);
+ this(ManagementFactory.getPlatformMBeanServer(), cache);
}
/**
@@ -128,7 +94,15 @@
String resourceName = resource.getObjectName();
ObjectName objectName = new ObjectName(getObjectName(resourceName));
if (!mBeanServer.isRegistered(objectName)) {
- mBeanServer.registerMBean(resource, objectName);
+ try {
+ mBeanServer.registerMBean(resource, objectName);
+ } catch (InstanceAlreadyExistsException e) {
+ //this might happen if multiple instances are trying to concurrently
register same objectName
+ log.info("Could not register object with name:" + objectName
+ "(" + e.getMessage() + ")");
+ }
+ } else {
+ if (log.isInfoEnabled())
+ log.info("Could not register object with name: " +
objectName);
}
}
}
@@ -169,22 +143,19 @@
return resourceDMBeans;
}
- private void processBaseName(ObjectName baseName) {
- if (baseName != null) {
- this.objectNameBase = baseName.getCanonicalName();
+ private void processBaseName() {
+ String base = cache.getConfiguration().getJmxNameBase();
+ if (base != null) {
+ objectNameBase = base;
+ if (log.isTraceEnabled()) log.trace("Using custom base name: '" +
base + "'");
return;
}
- if (cache.getConfiguration().getCacheMode().equals(Configuration.CacheMode.LOCAL))
{
- objectNameBase = LOCAL_CACHE_PREFIX + ",instance=" +
Integer.toHexString(System.identityHashCode(cache));
- } else //the cache is clustered
- {
- objectNameBase = REPLICATED_CACHE_PREFIX +
cache.getConfiguration().getGlobalConfiguration().getClusterName();
- }
- objectNameBase = objectNameBase + ",cacheName=" + cache.getName();
+ objectNameBase = "horizon:" + CACHE_NAME_KEY + "=";
+ objectNameBase += cache.getName() + "(" +
cache.getConfiguration().getCacheModeString().toLowerCase() + ")";
}
public String getObjectName(String resourceName) {
- return objectNameBase + JMX_RESOURCE_KEY + resourceName;
+ return objectNameBase + "," + JMX_RESOURCE_KEY + "=" +
resourceName;
}
public String getObjectNameBase() {
Modified:
core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java
===================================================================
---
core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java 2009-03-10
10:56:24 UTC (rev 7895)
+++
core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java 2009-03-10
21:24:47 UTC (rev 7896)
@@ -34,7 +34,7 @@
* If {@link Configuration#isExposeManagementStatistics()} is true, then class will
register all the MBeans from the
* ConfigurationRegistry to the pltform MBean server.
* <p/>
- * Note: to enable platform MBeanServer the following system property should be passet to
the JVM:
+ * Note: to enable platform MBeanServer the following system property should be passet to
the Sun JVM:
* <b>-Dcom.sun.management.jmxremote</b>.
*
* @author Mircea.Markus(a)jboss.com
Modified: core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd
===================================================================
--- core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd 2009-03-10
10:56:24 UTC (rev 7895)
+++ core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd 2009-03-10
21:24:47 UTC (rev 7896)
@@ -123,6 +123,7 @@
<xs:complexType name="jmxStatisticsType">
<xs:attribute name="enabled" type="tns:booleanType"/>
+ <xs:attribute name="jmxNameBase" type="xs:string"/>
</xs:complexType>
<xs:complexType name="lazyDeserialization">
Modified:
core/branches/flat/src/test/java/org/horizon/config/parsing/XmlFileParsingTest.java
===================================================================
---
core/branches/flat/src/test/java/org/horizon/config/parsing/XmlFileParsingTest.java 2009-03-10
10:56:24 UTC (rev 7895)
+++
core/branches/flat/src/test/java/org/horizon/config/parsing/XmlFileParsingTest.java 2009-03-10
21:24:47 UTC (rev 7896)
@@ -111,6 +111,10 @@
assert tableManipulation.getDataColumnType().equals("BLOB");
assert tableManipulation.isDropTableOnExit();
assert !tableManipulation.isCreateTableOnStart();
+
+ c = namedCaches.get("withJmxEnabled");
+ assert c.isExposeManagementStatistics();
+ assert c.getJmxNameBase().equals("horizonDomain:aKey=aValue");
}
public void testConfigurationMerging() throws IOException {
Added: core/branches/flat/src/test/java/org/horizon/jmx/JmxRegistrationManagerTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/jmx/JmxRegistrationManagerTest.java
(rev 0)
+++
core/branches/flat/src/test/java/org/horizon/jmx/JmxRegistrationManagerTest.java 2009-03-10
21:24:47 UTC (rev 7896)
@@ -0,0 +1,163 @@
+package org.horizon.jmx;
+
+import org.horizon.AdvancedCache;
+import org.horizon.Cache;
+import org.horizon.config.Configuration;
+import org.horizon.config.GlobalConfiguration;
+import org.horizon.interceptors.CacheMgmtInterceptor;
+import org.horizon.manager.CacheManager;
+import org.horizon.manager.DefaultCacheManager;
+import org.horizon.test.TestingUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tester class for {@link JmxRegistrationManager}.
+ *
+ * @author Mircea.Markus(a)jboss.com
+ * @author <a href="mailto:galder.zamarreno@jboss.com">Galder
Zamarreno</a>
+ * @since 1.0
+ */
+@Test(groups = "functional", testName =
"jmx.JmxRegistrationManagerTest")
+public class JmxRegistrationManagerTest {
+
+ private MBeanServer mBeanServer;
+ private List<CacheManager> cacheManagers = new ArrayList<CacheManager>();
+
+ @BeforeMethod
+ public void setUp() {
+ mBeanServer = MBeanServerFactory.createMBeanServer();
+// mBeanServer = ManagementFactory.getPlatformMBeanServer();
+ cacheManagers.clear();
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ MBeanServerFactory.releaseMBeanServer(mBeanServer);
+ for (CacheManager cacheManager : cacheManagers) {
+ TestingUtil.killCacheManagers(cacheManager);
+ }
+ cacheManagers.clear();
+ }
+
+ public void testRegisterLocalCache() throws Exception {
+ CacheManager cm = TestingUtil.createLocalCacheManager();
+ cacheManagers.add(cm);
+ cm.start();
+ Configuration configuration = config();
+ configuration.setCacheMode(Configuration.CacheMode.LOCAL);
+ cm.defineCache("first", configuration);
+ Cache first = cm.getCache("first");
+
+ JmxRegistrationManager regManager = new JmxRegistrationManager(mBeanServer,
(AdvancedCache) first);
+ regManager.registerAllMBeans();
+ String name =
regManager.getObjectName(CacheMgmtInterceptor.class.getSimpleName());
+ ObjectName name1 = new ObjectName(name);
+ assert mBeanServer.isRegistered(name1);
+ regManager.unregisterAllMBeans();
+ assert !mBeanServer.isRegistered(name1);
+ assertCorrectJmxName(name1, first);
+ }
+
+ public void testRegisterReplicatedCache() throws Exception {
+ GlobalConfiguration globalConfiguration =
GlobalConfiguration.getClusteredDefault();
+ CacheManager cm = new DefaultCacheManager(globalConfiguration);
+ cacheManagers.add(cm);
+ cm.start();
+ Configuration configurationOverride = config();
+ configurationOverride.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ cm.defineCache("first", configurationOverride);
+ Cache first = cm.getCache("first");
+
+ JmxRegistrationManager regManager = new JmxRegistrationManager(mBeanServer,
(AdvancedCache) first);
+ regManager.registerAllMBeans();
+ String name =
regManager.getObjectName(CacheMgmtInterceptor.class.getSimpleName());
+ ObjectName name1 = new ObjectName(name);
+ assertCorrectJmxName(name1, first);
+ assert mBeanServer.isRegistered(name1);
+ regManager.unregisterAllMBeans();
+ assert !mBeanServer.isRegistered(name1);
+ }
+
+ public void testLocalAndReplicatedCache() throws Exception {
+ GlobalConfiguration globalConfiguration =
GlobalConfiguration.getClusteredDefault();
+ CacheManager cm = new DefaultCacheManager(globalConfiguration);
+ cacheManagers.add(cm);
+ cm.start();
+ Configuration replicated = config();
+ Configuration local = config();
+ replicated.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ local.setCacheMode(Configuration.CacheMode.LOCAL);
+ cm.defineCache("replicated", replicated);
+ cm.defineCache("local", local);
+ Cache replicatedCache = cm.getCache("replicated");
+ Cache localCache = cm.getCache("local");
+
+ JmxRegistrationManager replicatedRegManager = new
JmxRegistrationManager(mBeanServer, (AdvancedCache) replicatedCache);
+ JmxRegistrationManager localRegManager = new JmxRegistrationManager(mBeanServer,
(AdvancedCache) localCache);
+ replicatedRegManager.registerAllMBeans();
+ localRegManager.registerAllMBeans();
+
+ String replicatedtCMgmtIntName =
replicatedRegManager.getObjectName(CacheMgmtInterceptor.class.getSimpleName());
+ String localCMgmtIntName =
localRegManager.getObjectName(CacheMgmtInterceptor.class.getSimpleName());
+ ObjectName replObjectName = new ObjectName(replicatedtCMgmtIntName);
+ ObjectName localObjName = new ObjectName(localCMgmtIntName);
+ assertCorrectJmxName(replObjectName, replicatedCache);
+
+ assert mBeanServer.isRegistered(replObjectName);
+ assert mBeanServer.isRegistered(localObjName);
+ assert !localCMgmtIntName.equals(replicatedtCMgmtIntName);
+
+ replicatedRegManager.unregisterAllMBeans();
+ localRegManager.unregisterAllMBeans();
+ assert !mBeanServer.isRegistered(new ObjectName(localCMgmtIntName));
+ assert !mBeanServer.isRegistered(new ObjectName(replicatedtCMgmtIntName));
+ }
+
+ public void testCustomCacheName() throws Exception {
+ CacheManager cm = TestingUtil.createLocalCacheManager();
+ cacheManagers.add(cm);
+ cm.start();
+ Configuration configuration = config();
+
configuration.setJmxNameBase("mircea:aKey=aValue,secondKey=secondValue");
+ configuration.setCacheMode(Configuration.CacheMode.LOCAL);
+ cm.defineCache("first", configuration);
+ Cache cache = cm.getCache("first");
+
+ JmxRegistrationManager regManager = new JmxRegistrationManager(mBeanServer,
(AdvancedCache) cache);
+ regManager.registerAllMBeans();
+
+ String name =
regManager.getObjectName(CacheMgmtInterceptor.class.getSimpleName());
+ ObjectName name1 = new ObjectName(name);
+ assert mBeanServer.isRegistered(name1);
+ regManager.unregisterAllMBeans();
+ assert !mBeanServer.isRegistered(name1);
+
+
+ assert name1.getDomain().equals("mircea");
+ assert name1.getKeyProperty("aKey").equals("aValue");
+ assert
name1.getKeyProperty("secondKey").equals("secondValue");
+ assert name1.getKeyProperty(JmxRegistrationManager.JMX_RESOURCE_KEY) != null;
+ }
+
+ private void assertCorrectJmxName(ObjectName objectName, Cache cache) {
+ assert
objectName.getKeyProperty(JmxRegistrationManager.CACHE_NAME_KEY).startsWith(cache.getName());
+ String cacheModeStr = cache.getConfiguration().getCacheModeString().toLowerCase();
+ assert
objectName.getKeyProperty(JmxRegistrationManager.CACHE_NAME_KEY).contains(cacheModeStr);
+ assert objectName.getKeyProperty(JmxRegistrationManager.JMX_RESOURCE_KEY) != null;
+ }
+
+
+ private Configuration config() {
+ Configuration configuration = new Configuration();
+ configuration.setExposeManagementStatistics(true);
+ return configuration;
+ }
+}
Property changes on:
core/branches/flat/src/test/java/org/horizon/jmx/JmxRegistrationManagerTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: core/branches/flat/src/test/java/org/horizon/jmx/ResourceDMBeanTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/jmx/ResourceDMBeanTest.java
(rev 0)
+++ core/branches/flat/src/test/java/org/horizon/jmx/ResourceDMBeanTest.java 2009-03-10
21:24:47 UTC (rev 7896)
@@ -0,0 +1,35 @@
+package org.horizon.jmx;
+
+import org.horizon.jmx.annotations.ManagedOperation;
+import org.testng.annotations.Test;
+
+/**
+ * /** Tester class for {@link ResourceDMBean}.
+ *
+ * @author Mircea.Markus(a)jboss.com
+ * @since 1.0
+ */
+@Test(groups = "unit", testName = "jmx.ResourceDMBeanTest")
+public class ResourceDMBeanTest {
+
+ /**
+ * If we have a method in the base class that is annotated as @ManagedOperation, will
this be seen the same way in
+ * the inherited class?
+ */
+ public void testInheritedMethod() {
+ Bbb bbb = new Bbb();
+ ResourceDMBean resourceDMBean = new ResourceDMBean(bbb);
+ assert resourceDMBean.isOperationRegistred("baseMethod");
+ }
+
+ static class Aaa {
+ @ManagedOperation
+ public void baseMethod() {
+ }
+ }
+
+ static class Bbb extends Aaa {
+ public void localMethod() {
+ }
+ }
+}
Property changes on:
core/branches/flat/src/test/java/org/horizon/jmx/ResourceDMBeanTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: core/branches/flat/src/test/resources/configs/named-cache-test.xml
===================================================================
--- core/branches/flat/src/test/resources/configs/named-cache-test.xml 2009-03-10 10:56:24
UTC (rev 7895)
+++ core/branches/flat/src/test/resources/configs/named-cache-test.xml 2009-03-10 21:24:47
UTC (rev 7896)
@@ -30,6 +30,7 @@
<default>
<locking concurrencyLevel="100"
lockAcquisitionTimeout="1000"/>
+ <jmxStatistics enabled="false"/>
</default>
<namedCache name="transactional">
@@ -100,4 +101,11 @@
</loaders>
</namedCache>
+ <namedCache name="withJmxEnabled">
+ <clustering>
+ <async useReplQueue="true" replQueueInterval="100"
replQueueMaxElements="200"/>
+ </clustering>
+ <jmxStatistics enabled="true"
jmxNameBase="horizonDomain:aKey=aValue"/>
+ </namedCache>
+
</horizon>