FELIX-2897 Add support for JMX support in the Jetty Container

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1174722 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/jetty/pom.xml b/http/jetty/pom.xml
index a5cb433..6e6a5a4 100644
--- a/http/jetty/pom.xml
+++ b/http/jetty/pom.xml
@@ -94,6 +94,11 @@
         </dependency>
         <dependency>
             <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty-management</artifactId>
+            <version>6.1.24</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
             <artifactId>jetty-sslengine</artifactId>
             <version>6.1.24</version>
         </dependency>
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
index 6053b5e..d57c627 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
@@ -67,6 +67,9 @@
     /** Felix specific property to control whether Jetty uses NIO or not for HTTPS. Valid values are "true", "false". Default is the value of org.apache.felix.http.nio */
     public static final String  FELIX_HTTPS_NIO = "org.apache.felix.https.nio";
 
+    /** Felix specific property to enable Jetty MBeans. Valid values are "true", "false". Default is false */
+    public static final String  FELIX_HTTP_MBEANS = "org.apache.felix.http.mbeans";
+
     private final BundleContext context;
     private boolean debug;
     private int httpPort;
@@ -81,6 +84,7 @@
     private String clientcert;
     private boolean useHttpNio;
     private boolean useHttpsNio;
+    private boolean registerMBeans;
 
     public JettyConfig(BundleContext context)
     {
@@ -123,6 +127,11 @@
         return this.useHttpsNio;
     }
 
+    public boolean isRegisterMBeans()
+    {
+        return this.registerMBeans;
+    }
+
     public int getHttpPort()
     {
         return this.httpPort;
@@ -187,6 +196,7 @@
         this.clientcert = getProperty(props, FELIX_HTTPS_CLIENT_CERT, "none");
         this.useHttpNio = getBooleanProperty(props, FELIX_HTTP_NIO, true);
         this.useHttpsNio = getBooleanProperty(props, FELIX_HTTPS_NIO, this.useHttpNio);
+        this.registerMBeans = getBooleanProperty(props, FELIX_HTTP_MBEANS, false);
     }
 
     private String getProperty(Dictionary props, String name, String defValue)
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
index 328ae0a..096191f 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
@@ -51,6 +51,7 @@
     private DispatcherServlet dispatcher;
     private EventDispatcher eventDispatcher;
     private final HttpServiceController controller;
+    private MBeanServerTracker mbeanServerTracker;
 
     public JettyService(BundleContext context, DispatcherServlet dispatcher, EventDispatcher eventDispatcher,
         HttpServiceController controller)
@@ -131,6 +132,12 @@
             {
                 SystemLogger.error("Exception while stopping Jetty.", e);
             }
+
+            if (this.mbeanServerTracker != null)
+            {
+                this.mbeanServerTracker.close();
+                this.mbeanServerTracker = null;
+            }
         }
     }
 
@@ -145,7 +152,13 @@
 
             // HTTP/1.1 requires Date header if possible (it is)
             this.server.setSendDateHeader(true);
-            
+
+            if (this.config.isRegisterMBeans())
+            {
+                this.mbeanServerTracker = new MBeanServerTracker(this.context, this.server);
+                this.mbeanServerTracker.open();
+            }
+
             this.server.addUserRealm(realm);
 
             if (this.config.isUseHttp())
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/MBeanServerTracker.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/MBeanServerTracker.java
new file mode 100644
index 0000000..203155d
--- /dev/null
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/MBeanServerTracker.java
@@ -0,0 +1,56 @@
+/*
+ * 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.felix.http.jetty.internal;
+
+import javax.management.MBeanServer;
+
+import org.mortbay.jetty.Server;
+import org.mortbay.management.MBeanContainer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class MBeanServerTracker extends ServiceTracker
+{
+
+    private final Server server;
+
+    public MBeanServerTracker(final BundleContext context, final Server server)
+    {
+        super(context, MBeanServer.class.getName(), null);
+        this.server = server;
+    }
+
+    @Override
+    public Object addingService(ServiceReference reference)
+    {
+        MBeanServer server = (MBeanServer) super.addingService(reference);
+        MBeanContainer mBeanContainer = new MBeanContainer(server);
+        this.server.getContainer().addEventListener(mBeanContainer);
+        return mBeanContainer;
+    }
+
+    @Override
+    public void removedService(ServiceReference reference, Object service)
+    {
+        MBeanContainer mBeanContainer = (MBeanContainer) service;
+        this.server.getContainer().removeEventListener(mBeanContainer);
+        super.removedService(reference, mBeanContainer.getMBeanServer());
+    }
+}
diff --git a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties
index a175b74..7034cb2 100644
--- a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -83,4 +83,8 @@
 org.apache.felix.https.nio.name = NIO for HTTPS
 org.apache.felix.https.nio.description = Wether or not to use NIO for HTTP. \
  Defaults to the value of the NIO for HTTP property. Only used if HTTPS is \
- enabled.
\ No newline at end of file
+ enabled.
+
+org.apache.felix.http.mbeans.name = Register MBeans
+org.apache.felix.http.mbeans.description = Whether or not to use register \
+ JMX MBeans from the servlet container (Jetty).
\ No newline at end of file
diff --git a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml
index e4a3602..82ceeed 100644
--- a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml
+++ b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml
@@ -7,6 +7,7 @@
         <AD id="org.apache.felix.https.enable" type="Boolean" default="false" name="%org.apache.felix.https.enable.name" description="%org.apache.felix.https.enable.description"/>
         <AD id="org.osgi.service.http.port.secure" type="Integer" default="433" name="%org.osgi.service.http.port.secure.name" description="%org.osgi.service.http.port.secure.description"/>
         <AD id="org.apache.felix.https.nio" type="Boolean" default="true" name="%org.apache.felix.https.nio.name" description="%org.apache.felix.https.nio.description"/>
+        <AD id="org.apache.felix.http.mbeans" type="Boolean" default="false" name="%org.apache.felix.http.mbeans.name" description="%org.apache.felix.http.mbeans.description"/>
         <AD id="org.apache.felix.https.keystore" type="String" name="%org.apache.felix.https.keystore.name" description="%org.apache.felix.https.keystore.description"/>
         <AD id="org.apache.felix.https.keystore.password" type="String" name="%org.apache.felix.https.keystore.password.name" description="%org.apache.felix.https.keystore.password.description"/>
         <AD id="org.apache.felix.https.keystore.key.password" type="String" name="%org.apache.felix.https.keystore.key.password.name" description="%org.apache.felix.https.keystore.key.password.description"/>