You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2010/04/17 04:20:12 UTC
svn commit: r935108 - in /camel/trunk: components/camel-jetty/
components/camel-jetty/src/main/java/org/apache/camel/component/jetty/
components/camel-jetty/src/test/java/org/apache/camel/component/jetty/
platforms/karaf/features/src/main/resources/ te...
Author: ningjiang
Date: Sat Apr 17 02:20:12 2010
New Revision: 935108
URL: http://svn.apache.org/viewvc?rev=935108&view=rev
Log:
CAMEL-2652 Allow camel-jetty to enable Jetty JMX extensions, Applied the patch with thanks to David
Added:
camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java (with props)
Modified:
camel/trunk/components/camel-jetty/pom.xml
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java
camel/trunk/platforms/karaf/features/src/main/resources/features.xml
camel/trunk/tests/camel-itest-karaf/pom.xml
camel/trunk/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/AbstractFeatureTest.java
Modified: camel/trunk/components/camel-jetty/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/pom.xml?rev=935108&r1=935107&r2=935108&view=diff
==============================================================================
--- camel/trunk/components/camel-jetty/pom.xml (original)
+++ camel/trunk/components/camel-jetty/pom.xml Sat Apr 17 02:20:12 2010
@@ -66,7 +66,11 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-jmx</artifactId>
+ <version>${jetty-version}</version>
+ </dependency>
<!-- testing -->
<dependency>
<groupId>org.apache.camel</groupId>
Modified: camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java?rev=935108&r1=935107&r2=935108&view=diff
==============================================================================
--- camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java (original)
+++ camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java Sat Apr 17 02:20:12 2010
@@ -21,6 +21,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.management.MBeanServer;
+
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.RuntimeCamelException;
@@ -29,14 +31,16 @@ import org.apache.camel.component.http.H
import org.apache.camel.component.http.HttpComponent;
import org.apache.camel.component.http.HttpConsumer;
import org.apache.camel.component.http.HttpEndpoint;
+import org.apache.camel.spi.ManagementAgent;
+import org.apache.camel.spi.ManagementStrategy;
import org.apache.camel.util.CastUtils;
import org.apache.camel.util.IntrospectionSupport;
import org.apache.camel.util.URISupport;
-import org.apache.camel.util.UnsafeUriCharactersEncoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.client.Address;
import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
@@ -76,6 +80,7 @@ public class JettyHttpComponent extends
protected ThreadPool httpClientThreadPool;
protected Integer httpClientMinThreads;
protected Integer httpClientMaxThreads;
+ protected MBeanContainer mbContainer;
class ConnectorRef {
Server server;
@@ -110,6 +115,7 @@ public class JettyHttpComponent extends
Boolean throwExceptionOnFailure = getAndRemoveParameter(parameters, "throwExceptionOnFailure", Boolean.class);
Boolean bridgeEndpoint = getAndRemoveParameter(parameters, "bridgeEndpoint", Boolean.class);
Boolean matchOnUriPrefix = getAndRemoveParameter(parameters, "matchOnUriPrefix", Boolean.class);
+ Boolean enableJmx = getAndRemoveParameter(parameters, "enableJmx", Boolean.class);
// configure http client if we have url configuration for it
// http client is only used for jetty http producer (hence not very commonly used)
@@ -155,6 +161,10 @@ public class JettyHttpComponent extends
if (matchOnUriPrefix != null) {
endpoint.setMatchOnUriPrefix(matchOnUriPrefix);
}
+
+ if (enableJmx != null) {
+ endpoint.setEnableJmx(enableJmx);
+ }
setProperties(endpoint, parameters);
return endpoint;
@@ -184,6 +194,9 @@ public class JettyHttpComponent extends
LOG.warn("You use localhost interface! It means that no external connections will be available. Don't you want to use 0.0.0.0 instead (all network interfaces)?");
}
Server server = createServer();
+ if (endpoint.isEnableJmx()) {
+ enableJmx(server);
+ }
server.addConnector(connector);
connectorRef = new ConnectorRef(server, connector, createServletForConnector(server, connector, endpoint.getHandlers()));
@@ -202,6 +215,16 @@ public class JettyHttpComponent extends
connectorRef.servlet.connect(consumer);
}
}
+
+ private void enableJmx(Server server) {
+ MBeanContainer containerToRegister = getMbContainer();
+ if (containerToRegister != null) {
+ server.getContainer().addEventListener(containerToRegister);
+ // Since we may have many Servers running, don't tie the MBeanContainer
+ // to a Server lifecycle or we end up closing it while it is still in use.
+ //server.addBean(mbContainer);
+ }
+ }
private void enableSessionSupport(Server server) throws Exception {
ServletContextHandler context = (ServletContextHandler)server.getChildHandlerByClass(ServletContextHandler.class);
@@ -236,6 +259,13 @@ public class JettyHttpComponent extends
connectorRef.connector.stop();
connectorRef.server.stop();
CONNECTORS.remove(connectorKey);
+ // Camel controls the lifecycle of these entities so remove the
+ // registered MBeans when Camel is done with the managed objects.
+ MBeanContainer containerToClean = getMbContainer();
+ if (containerToClean != null) {
+ containerToClean.removeBean(connectorRef.server);
+ containerToClean.removeBean(connectorRef.connector);
+ }
}
}
}
@@ -379,6 +409,33 @@ public class JettyHttpComponent extends
this.httpClientMaxThreads = httpClientMaxThreads;
}
+ public synchronized MBeanContainer getMbContainer() {
+ // If null, provide the default implementation.
+ if (mbContainer == null) {
+ MBeanServer mbs = null;
+
+ final ManagementStrategy mStrategy =
+ this.getCamelContext().getManagementStrategy();
+ final ManagementAgent mAgent = mStrategy.getManagementAgent();
+ if (mAgent != null) {
+ mbs = mAgent.getMBeanServer();
+ }
+
+ if (mbs != null) {
+ mbContainer = new MBeanContainer(mbs);
+ startMbContainer();
+ } else {
+ LOG.warn("JMX disabled in Camel Context. The Camel Context takes precedent and JMX will not be enabled in Jetty.");
+ }
+ }
+
+ return this.mbContainer;
+ }
+
+ public void setMbContainer(MBeanContainer mbContainer) {
+ this.mbContainer = mbContainer;
+ }
+
// Implementation methods
// -------------------------------------------------------------------------
protected CamelServlet createServletForConnector(Server server, Connector connector, List<Handler> handlers) throws Exception {
@@ -422,6 +479,25 @@ public class JettyHttpComponent extends
server.setHandler(collection);
return server;
}
+
+ /**
+ * Starts {@link #mbContainer} and registers the
+ * container with itself as a managed bean logging an error
+ * if there is a problem starting the container. Does nothing
+ * if {@link #mbContainer} is {@code null}.
+ */
+ protected void startMbContainer() {
+ if (mbContainer != null && !mbContainer.isStarted()) {
+ try {
+ mbContainer.start();
+ // Publish the container itself for consistency with
+ // traditional embedded Jetty configurations.
+ mbContainer.addBean(mbContainer);
+ } catch (Exception e) {
+ LOG.fatal("Could not start Jetty MBeanContainer. Jetty JMX extensions will remain disabled.", e);
+ }
+ }
+ }
@Override
protected void doStart() throws Exception {
@@ -433,6 +509,8 @@ public class JettyHttpComponent extends
if (httpClient != null && !httpClient.isStarted()) {
httpClient.start();
}
+
+ startMbContainer();
}
@Override
@@ -442,7 +520,14 @@ public class JettyHttpComponent extends
for (ConnectorRef connectorRef : CONNECTORS.values()) {
connectorRef.server.removeConnector(connectorRef.connector);
connectorRef.connector.stop();
- connectorRef.server.stop();
+ connectorRef.server.stop();
+ // Camel controls the lifecycle of these entities so remove the
+ // registered MBeans when Camel is done with the managed objects.
+ MBeanContainer containerToClean = getMbContainer();
+ if (containerToClean != null) {
+ containerToClean.removeBean(connectorRef.server);
+ containerToClean.removeBean(connectorRef.connector);
+ }
}
CONNECTORS.clear();
}
@@ -453,5 +538,8 @@ public class JettyHttpComponent extends
LifeCycle lc = (LifeCycle) httpClientThreadPool;
lc.stop();
}
+ if (mbContainer != null) {
+ mbContainer.stop();
+ }
}
}
\ No newline at end of file
Modified: camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java?rev=935108&r1=935107&r2=935108&view=diff
==============================================================================
--- camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java (original)
+++ camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java Sat Apr 17 02:20:12 2010
@@ -37,6 +37,7 @@ public class JettyHttpEndpoint extends H
private List<Handler> handlers;
private HttpClient client;
private JettyHttpBinding jettyBinding;
+ private boolean enableJmx;
public JettyHttpEndpoint(JettyHttpComponent component, String uri, URI httpURL) throws URISyntaxException {
super(uri, component, httpURL);
@@ -98,4 +99,12 @@ public class JettyHttpEndpoint extends H
public void setJettyBinding(JettyHttpBinding jettyBinding) {
this.jettyBinding = jettyBinding;
}
+
+ public boolean isEnableJmx() {
+ return this.enableJmx;
+ }
+
+ public void setEnableJmx(boolean enableJmx) {
+ this.enableJmx = enableJmx;
+ }
}
Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java?rev=935108&view=auto
==============================================================================
--- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java (added)
+++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java Sat Apr 17 02:20:12 2010
@@ -0,0 +1,159 @@
+/**
+ * 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.component.jetty;
+
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+
+public class JettyEnableJmxTest extends CamelTestSupport {
+
+ private String serverUri0 =
+ "http://localhost:9080/myservice?enableJmx=true";
+ private String serverUri1 =
+ "http://localhost:9081/myservice?enableJmx=true";
+ private String serverUri2 =
+ "http://localhost:9082/myservice?enableJmx=false";
+ private String serverUri3 =
+ "http://localhost:9083/myservice?enableJmx=false";
+ private MBeanServerConnection mbsc;
+
+ @Override
+ public void tearDown() throws Exception {
+ releaseMBeanServers();
+ mbsc = null;
+ super.tearDown();
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ releaseMBeanServers();
+ super.setUp();
+ mbsc = getMBeanConnection();
+ }
+
+ @Test
+ public void testEnableJmxProperty() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ String expectedBody = "<html><body>foo</body></html>";
+ mock.expectedBodiesReceived(
+ expectedBody, expectedBody, expectedBody, expectedBody);
+ mock.expectedHeaderReceived("x", "foo");
+
+ template.requestBody(serverUri0 + "&x=foo", null, Object.class);
+ template.requestBody(serverUri1 + "&x=foo", null, Object.class);
+ template.requestBody(serverUri2 + "&x=foo", null, Object.class);
+ template.requestBody(serverUri3 + "&x=foo", null, Object.class);
+
+ assertMockEndpointsSatisfied();
+
+ Set<ObjectName> s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null);
+ assertEquals("Could not find 2 Jetty Server: " + s, 2, s.size());
+ }
+
+ @Test
+ public void testShutdown() throws Exception {
+ Set<ObjectName> s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null);
+ assertEquals("Could not find 2 Jetty Server: " + s, 2, s.size());
+
+ context.stop();
+
+ s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null);
+ assertEquals("Could not find 0 Jetty Server: " + s, 0, s.size());
+ }
+
+ @Test
+ public void testEndpointDisconnect() throws Exception {
+ Set<ObjectName> s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null);
+ assertEquals("Could not find 2 Jetty Server: " + s, 2, s.size());
+
+ context.stopRoute("route0");
+
+ s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null);
+ assertEquals("Could not find 1 Jetty Server: " + s, 1, s.size());
+
+ context.stopRoute("route2");
+ context.stopRoute("route3");
+
+ s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null);
+ assertEquals("Could not find 1 Jetty Server: " + s, 1, s.size());
+
+ context.stopRoute("route1");
+
+ s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null);
+ assertEquals("Could not find 0 Jetty Server: " + s, 0, s.size());
+ }
+
+ @Override
+ protected boolean useJmx() {
+ return true;
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() throws Exception {
+ from("jetty:" + serverUri0)
+ .routeId("route0")
+ .setBody().simple("<html><body>${in.header.x}</body></html>")
+ .to("mock:result");
+
+ from("jetty:" + serverUri1)
+ .routeId("route1")
+ .setBody().simple("<html><body>${in.header.x}</body></html>")
+ .to("mock:result");
+
+ from("jetty:" + serverUri2)
+ .routeId("route2")
+ .setBody().simple("<html><body>${in.header.x}</body></html>")
+ .to("mock:result");
+
+ from("jetty:" + serverUri3)
+ .routeId("route3")
+ .setBody().simple("<html><body>${in.header.x}</body></html>")
+ .to("mock:result");
+ }
+ };
+ }
+
+ protected void releaseMBeanServers() {
+ List<MBeanServer> servers =
+ (List<MBeanServer>)MBeanServerFactory.findMBeanServer(null);
+
+ for (MBeanServer server : servers) {
+ MBeanServerFactory.releaseMBeanServer(server);
+ }
+ }
+
+ protected MBeanServerConnection getMBeanConnection() throws Exception {
+ if (mbsc == null) {
+ mbsc = ManagementFactory.getPlatformMBeanServer();
+ }
+ return mbsc;
+ }
+}
Propchange: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: camel/trunk/platforms/karaf/features/src/main/resources/features.xml
URL: http://svn.apache.org/viewvc/camel/trunk/platforms/karaf/features/src/main/resources/features.xml?rev=935108&r1=935107&r2=935108&view=diff
==============================================================================
--- camel/trunk/platforms/karaf/features/src/main/resources/features.xml (original)
+++ camel/trunk/platforms/karaf/features/src/main/resources/features.xml Sat Apr 17 02:20:12 2010
@@ -119,10 +119,13 @@
<bundle>mvn:org.eclipse.jetty/jetty-http/${jetty-bundle-version}</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-client/${jetty-bundle-version}</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-continuation/${jetty-bundle-version}</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-jmx/${jetty-bundle-version}</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-server/${jetty-bundle-version}</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-security/${jetty-bundle-version}</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-servlet/${jetty-bundle-version}</bundle>
<bundle>mvn:org.eclipse.jetty/jetty-servlets/${jetty-bundle-version}</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-xml/${jetty-bundle-version}</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-webapp/${jetty-bundle-version}</bundle>
<feature version='${pom.version}'>camel-core</feature>
<feature version='${pom.version}'>camel-http</feature>
<bundle>mvn:org.apache.camel/camel-jetty/${pom.version}</bundle>
Modified: camel/trunk/tests/camel-itest-karaf/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-karaf/pom.xml?rev=935108&r1=935107&r2=935108&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-karaf/pom.xml (original)
+++ camel/trunk/tests/camel-itest-karaf/pom.xml Sat Apr 17 02:20:12 2010
@@ -104,6 +104,7 @@
<plugin>
<groupId>org.apache.servicemix.tooling</groupId>
<artifactId>depends-maven-plugin</artifactId>
+ <version>1.2</version>
<executions>
<execution>
<id>generate-depends-file</id>
Modified: camel/trunk/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/AbstractFeatureTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/AbstractFeatureTest.java?rev=935108&r1=935107&r2=935108&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/AbstractFeatureTest.java (original)
+++ camel/trunk/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/AbstractFeatureTest.java Sat Apr 17 02:20:12 2010
@@ -159,7 +159,7 @@ public abstract class AbstractFeatureTes
scanFeatures(mavenBundle().groupId("org.apache.camel.karaf").
artifactId("apache-camel").versionAsInProject().type("xml/features"),
- "camel-osgi", "camel-" + feature),
+ "camel-spring-osgi", "camel-" + feature),
//cleanCaches(),
felix());