You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2007/08/20 19:25:14 UTC

svn commit: r567761 - in /activemq/camel/trunk/camel-core/src: main/java/org/apache/camel/management/ test/java/org/apache/camel/management/

Author: jstrachan
Date: Mon Aug 20 10:25:14 2007
New Revision: 567761

URL: http://svn.apache.org/viewvc?rev=567761&view=rev
Log:
applied patch for CAMEL-104 with thanks - I fixed a typo on the package name too :).

Added:
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java   (with props)
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingPropertiesTest.java   (with props)
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java   (with props)
Modified:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationAgentImpl.java

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationAgentImpl.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationAgentImpl.java?rev=567761&r1=567760&r2=567761&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationAgentImpl.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationAgentImpl.java Mon Aug 20 10:25:14 2007
@@ -17,32 +17,55 @@
  */
 package org.apache.camel.management;
 
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.JMException;
 import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
 import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectInstance;
 import javax.management.ObjectName;
 import javax.management.modelmbean.InvalidTargetObjectTypeException;
 import javax.management.modelmbean.ModelMBeanInfo;
 import javax.management.modelmbean.RequiredModelMBean;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.spi.InstrumentationAgent;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
 import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
 
 public class InstrumentationAgentImpl implements InstrumentationAgent, CamelContextAware {
 
+    private static final transient Log LOG = LogFactory.getLog(InstrumentationAgentImpl.class);
+    
+	public static final String SYSTEM_PROPERTY_JMX = "org.apache.camel.jmx";
+	public static final String DEFAULT_DOMAIN = "org.apache.camel";
+	public static final String DEFAULT_HOST = "localhost";
+	public static final int DEFAULT_PORT = 1099;
+	
 	private MBeanServer server;
 	private CamelContext context;
     private Set<ObjectName> mbeans = new HashSet<ObjectName>();
-    MetadataMBeanInfoAssembler assembler;
+    private MetadataMBeanInfoAssembler assembler;
+    private JMXConnectorServer cs;
+	private boolean jmxEnabled = false;
+	private String jmxDomainName = null;
+	private int jmxConnectorPort = 0;
 	
     public InstrumentationAgentImpl() {
     	assembler = new MetadataMBeanInfoAssembler();
@@ -58,6 +81,7 @@
 
 	public void setMBeanServer(MBeanServer server) {
 		this.server = server;
+		jmxEnabled = true;
 	}
 	
 	public MBeanServer getMBeanServer() {
@@ -91,10 +115,15 @@
 
 	public void start() {
 		if (context == null) {
-			// LOG warning
+            LOG.warn("Cannot start InstrumentationAgent: CamelContext not set");
 			return;
 		}
 		
+		if (server == null) {
+			// The MBeanServer was not injected
+			createMBeanServer();
+		}
+
 		if (context instanceof DefaultCamelContext) {
 			DefaultCamelContext dc = (DefaultCamelContext)context;
 			InstrumentationLifecycleStrategy ls = new InstrumentationLifecycleStrategy(this); 
@@ -106,14 +135,21 @@
     public void stop() {
         //Using the array to hold the busMBeans to avoid the CurrentModificationException
         Object[] mBeans = mbeans.toArray();
+        int caught = 0;
         for (Object name : mBeans) {
         	mbeans.remove((ObjectName)name);
             try {
                 unregister((ObjectName)name);
             } catch (JMException jmex) {
-                // log
+                LOG.info("Exception unregistering MBean", jmex);
+                caught++;
             }
         }
+        if (caught > 0) {
+        	LOG.warn("A number of " + caught + 
+        		" exceptions caught while unregistering MBeans during stop operation.  " + 
+        		"See INFO log for details."); 
+        }
     }
     
     private void registerMBeanWithServer(Object obj, ObjectName name, boolean forceRegistration) 
@@ -135,4 +171,121 @@
 	    	mbeans.add(name);
 	    }
     }
+
+	public void enableJmx(String domainName, int port) {
+		jmxEnabled = true;
+		jmxDomainName = domainName;
+		jmxConnectorPort = port;
+	}
+
+    protected void createMBeanServer() {
+        String hostName = DEFAULT_HOST;
+        boolean canAccessSystemProps = true;
+        try {
+        	// we'll do it this way mostly to determine if we should lookup the hostName
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                sm.checkPropertiesAccess();
+            }
+        }
+        catch (SecurityException se) {
+            canAccessSystemProps = false;
+        }
+
+    	if (canAccessSystemProps) {
+    		if (!jmxEnabled) {
+    			jmxEnabled = null != System.getProperty(SYSTEM_PROPERTY_JMX);
+    			if (!jmxEnabled) {
+    				// we're done here
+    				return;
+    			}
+    		}
+    		
+    		if (jmxDomainName == null) {
+            	jmxDomainName = System.getProperty(SYSTEM_PROPERTY_JMX + ".domain");
+            	if (jmxDomainName == null || jmxDomainName.length() == 0) {
+            		jmxDomainName = DEFAULT_DOMAIN;
+            	}
+    		}
+    		
+        	if (jmxConnectorPort <= 0) {
+        		String portKey = SYSTEM_PROPERTY_JMX + ".port";
+	        	String portValue = System.getProperty(portKey);
+	        	if (portValue != null && portValue.length() > 0) {
+	        		try {
+	        			jmxConnectorPort = Integer.parseInt(portValue);
+	        		}
+	        		catch (NumberFormatException nfe) {
+	        			LOG.info("Invalid port number specified via System property [" + 
+	        				portKey + "=" + portValue + "].  Using default: " + DEFAULT_PORT);
+	        			jmxConnectorPort = DEFAULT_PORT;
+	        		}
+	        	}
+        	}
+        	
+        	try {
+                hostName = InetAddress.getLocalHost().getHostName();
+        	}
+        	catch (UnknownHostException uhe) {
+    			LOG.info("Cannot determine host name.  Using default: " + DEFAULT_PORT, uhe);
+                hostName = DEFAULT_HOST;
+        	}
+    	}
+    	else {
+			jmxDomainName = jmxDomainName != null ? jmxDomainName : DEFAULT_DOMAIN;
+			jmxConnectorPort = jmxConnectorPort > 0 ? jmxConnectorPort : DEFAULT_PORT;
+            hostName = DEFAULT_HOST;
+    	}
+    	
+    	if (!jmxEnabled) {
+    		return;
+    	}
+
+    	// jmx is enabled but there's no MBeanServer, so create one
+    	List servers = MBeanServerFactory.findMBeanServer(jmxDomainName);
+    	if (servers.size() == 0) {
+    		server = MBeanServerFactory.createMBeanServer(jmxDomainName);
+    	}
+    	else {
+    		server = (MBeanServer)servers.get(0);
+    	}
+
+    	// we need a connector too
+    	try {
+            createJmxConnector(hostName);
+    	}
+    	catch (IOException ioe) {
+			LOG.warn("Could not create and start jmx connector.", ioe);
+    	}
+    }
+    
+    protected void createJmxConnector(String host) throws IOException {
+    	if (jmxConnectorPort > 0) {
+	        try {
+	            LocateRegistry.createRegistry(jmxConnectorPort);
+	        } catch (RemoteException ex) {
+	            // the registry may had been created
+	            LocateRegistry.getRegistry(jmxConnectorPort);
+	        }
+	
+	        // Create an RMI connector and start it
+	        JMXServiceURL url = new JMXServiceURL(
+        		  "service:jmx:rmi:///jndi/rmi://" + host + ":" + jmxConnectorPort +  "/jmxrmi");
+			cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
+			
+	         // Start the connector server asynchronously (in a separate thread).
+	        Thread connectorThread = new Thread() {
+	            public void run() {
+	                try {
+	                    cs.start();
+	                } catch (IOException ioe) {
+	        			LOG.warn("Could not start jmx connector thread.", ioe);
+	                } 
+	            }
+	        };
+	        connectorThread.setName("JMX Connector Thread [" + url + "]");
+	        connectorThread.start();
+			LOG.info("Jmx connector thread started on " + url);
+    	}
+    }    
 }

Added: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java?rev=567761&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java (added)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java Mon Aug 20 10:25:14 2007
@@ -0,0 +1,76 @@
+/**
+ *
+ * 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.camel.management;
+
+import java.io.IOException;
+import java.util.Set;
+
+import javax.management.ObjectName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.management.InstrumentationAgentImpl;
+
+public class JmxInstrumentationUsingDefaultsTest extends ContextTestSupport {
+	
+	public static final int DEFAULT_PORT = 1099;
+
+	protected InstrumentationAgentImpl iAgent;
+	protected String domainName;
+
+	protected void enableJmx() {
+		iAgent.enableJmx(null, 0);
+		domainName = InstrumentationAgentImpl.DEFAULT_DOMAIN;
+	}
+	
+    protected CamelContext createCamelContext() throws Exception {
+    	CamelContext context = super.createCamelContext();
+    	createInstrumentationAgent(context, DEFAULT_PORT);
+    	return context;
+    }
+
+    protected void createInstrumentationAgent(CamelContext context, int port) throws IOException {
+    	iAgent = new InstrumentationAgentImpl();
+    	iAgent.setCamelContext(context);
+    	enableJmx();
+    	iAgent.start();
+    }
+
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start").to("mock:end");
+            }
+        };
+    }
+
+    public void testAgentConfiguration() throws Exception {
+    	assertNotNull(iAgent.getMBeanServer()); 
+    	assertEquals(domainName, iAgent.getMBeanServer().getDefaultDomain()); 
+    }
+    
+    public void testMBeansRegistered() throws Exception {
+        resolveMandatoryEndpoint("mock:end", MockEndpoint.class);
+        
+        ObjectName name = new ObjectName(domainName + ":type=Endpoints,*");
+        Set s = iAgent.getMBeanServer().queryNames(name, null);
+        assertTrue(s.size() == 2);
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingPropertiesTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingPropertiesTest.java?rev=567761&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingPropertiesTest.java (added)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingPropertiesTest.java Mon Aug 20 10:25:14 2007
@@ -0,0 +1,46 @@
+/**
+ *
+ * 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.camel.management;
+
+import org.apache.camel.management.InstrumentationAgentImpl;
+
+public class JmxInstrumentationUsingPropertiesTest extends JmxInstrumentationUsingDefaultsTest {
+
+    @Override
+    protected void setUp() throws Exception {
+		domainName = "org.apache.camel-properties";
+    	System.setProperty(InstrumentationAgentImpl.SYSTEM_PROPERTY_JMX, "");
+    	System.setProperty(InstrumentationAgentImpl.SYSTEM_PROPERTY_JMX + ".domain", domainName);
+    	System.setProperty(InstrumentationAgentImpl.SYSTEM_PROPERTY_JMX + ".port", "1099");
+    	super.setUp();
+    }
+	
+    @Override
+    protected void tearDown() throws Exception {
+    	// restore environment to original state
+    	System.setProperty(InstrumentationAgentImpl.SYSTEM_PROPERTY_JMX, "");
+    	System.setProperty(InstrumentationAgentImpl.SYSTEM_PROPERTY_JMX + ".domain", "");
+    	System.setProperty(InstrumentationAgentImpl.SYSTEM_PROPERTY_JMX + ".port", "");
+    	super.tearDown();
+    }
+	
+    @Override
+	protected void enableJmx() {
+		// do not enable here, System properties should do the job
+	}
+}

Propchange: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingPropertiesTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java?rev=567761&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java (added)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java Mon Aug 20 10:25:14 2007
@@ -0,0 +1,27 @@
+/**
+ *
+ * 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.camel.management;
+
+public class JmxInstrumentationWithConnectorTest extends JmxInstrumentationUsingDefaultsTest {
+
+    @Override
+	protected void enableJmx() {
+		domainName = "org.apache.camel-explicit";
+		iAgent.enableJmx(domainName, 1099);
+	}
+}

Propchange: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native