You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2009/04/15 06:58:06 UTC

svn commit: r765051 - in /tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool: ./ interceptor/ jmx/

Author: fhanik
Date: Wed Apr 15 04:58:06 2009
New Revision: 765051

URL: http://svn.apache.org/viewvc?rev=765051&view=rev
Log:
JMX needs to be handled a bit differently. Random object names are not all that great.
In this way, one can control the JMX registration completely from the outside.


Modified:
    tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
    tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
    tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
    tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java
    tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
    tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
    tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml

Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java Wed Apr 15 04:58:06 2009
@@ -779,17 +779,18 @@
     protected void finalize(PooledConnection con) {
         
     }
+    
+    public org.apache.tomcat.jdbc.pool.jmx.ConnectionPool getJmxPool() {
+        return jmxPool;
+    }
 
     protected void startJmx() {
         try {
-            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-            ObjectName name = new ObjectName(POOL_JMX_TYPE_PREFIX+"ConnectionPool,name="+getName());
             if ("1.5".equals(System.getProperty("java.specification.version"))) {
                 jmxPool = new org.apache.tomcat.jdbc.pool.jmx.ConnectionPool(this);
             } else {
                 jmxPool = new org.apache.tomcat.jdbc.pool.jmx.ConnectionPool(this,true);
             }
-            mbs.registerMBean(jmxPool, name);
         } catch (Exception x) {
             log.warn("Unable to start JMX integration for connection pool. Instance["+getName()+"] can't be monitored.",x);
         }
@@ -797,10 +798,6 @@
 
     protected void stopJmx() {
         try {
-            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-            ObjectName name = new ObjectName(POOL_JMX_TYPE_PREFIX+"ConnectionPool,name="+getName());
-            if (mbs.isRegistered(name))
-                mbs.unregisterMBean(name);
             jmxPool = null;
         }catch (Exception x) {
             log.warn("Unable to stop JMX integration for connection pool. Instance["+getName()+"].",x);

Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java Wed Apr 15 04:58:06 2009
@@ -16,9 +16,19 @@
  */
 package org.apache.tomcat.jdbc.pool;
 
+import java.lang.management.ManagementFactory;
 import java.sql.SQLException;
+import java.util.Hashtable;
 import java.util.Properties;
 
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean;
+
 
 /**
  * A DataSource that can be instantiated through IoC and implements the DataSource interface
@@ -26,7 +36,7 @@
  * @author Filip Hanik
  * @version 1.0
  */
-public class DataSource extends DataSourceProxy implements javax.sql.DataSource, org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean {
+public class DataSource extends DataSourceProxy implements MBeanRegistration,javax.sql.DataSource, org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean {
 
     public DataSource() {
         super();
@@ -37,6 +47,63 @@
     }
 
 //===============================================================================
+//  Register the actual pool itself under the tomcat.jdbc domain
+//===============================================================================
+    protected volatile ObjectName oname = null;
+    public void postDeregister() {
+        if (oname!=null) unregisterJmx();
+    }
+
+    public void postRegister(Boolean registrationDone) {
+    }
+
+
+    public void preDeregister() throws Exception {
+    }
+
+    public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
+        try {
+            this.oname = createObjectName(name);
+            if (oname!=null) registerJmx();
+        }catch (MalformedObjectNameException x) {
+            log.error("Unable to create object name for JDBC pool.",x);
+        }
+        return name;   
+    }
+    
+    public ObjectName createObjectName(ObjectName original) throws MalformedObjectNameException {
+        String domain = "tomcat.jdbc";
+        Hashtable<String,String> properties = original.getKeyPropertyList();
+        String origDomain = original.getDomain();
+        properties.put("type", "ConnectionPool");
+        properties.put("class", this.getClass().getName());
+        if (original.getKeyProperty("path")!=null) {
+            properties.put("engine", origDomain);
+        }
+        ObjectName name = new ObjectName(domain,properties);
+        return name;
+    }
+    
+    protected void registerJmx() {
+        try {
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+            mbs.registerMBean(pool.getJmxPool(), oname);
+        } catch (Exception e) {
+            log.error("Unable to register JDBC pool with JMX",e);
+        }
+    }
+    
+    protected void unregisterJmx() {
+        try {
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+            mbs.unregisterMBean(oname);
+        } catch (InstanceNotFoundException ignore) {
+        } catch (Exception e) {
+            log.error("Unable to unregister JDBC pool with JMX",e);
+        }
+    }
+
+//===============================================================================
 //  Expose JMX attributes through Tomcat's dynamic reflection
 //===============================================================================
     public void checkAbandoned() {
@@ -62,6 +129,10 @@
             throw new RuntimeException(x);
         }
     }
+    
+    public int getNumActive() {
+        return getActive();
+    }
 
     public String getConnectionProperties() {
         try {
@@ -110,6 +181,10 @@
             throw new RuntimeException(x);
         }
     }
+    
+    public int getNumIdle() {
+        return getIdle();
+    }
 
     public int getInitialSize() {
         try {

Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java Wed Apr 15 04:58:06 2009
@@ -176,7 +176,9 @@
             if (pool != null) {
                 final ConnectionPool p = pool;
                 pool = null;
-                if (p!=null) p.close(all);
+                if (p!=null) {
+                    p.close(all);
+                }
             }
         }catch (Exception x) {
             log.warn("Error duing connection pool closure.", x);
@@ -197,7 +199,7 @@
     public String toString() {
         return super.toString()+"{"+getPoolProperties()+"}";
     }
-
+    
 /*-----------------------------------------------------------------------*/
 //      PROPERTIES WHEN NOT USED WITH FACTORY
 /*------------------------------------------------------------------------*/

Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java Wed Apr 15 04:58:06 2009
@@ -50,8 +50,8 @@
  *
  */
 public class SlowQueryReportJmx extends SlowQueryReport {
-    public static final String SLOW_QUERY_NOTIFICATION = "Slow query";
-    public static final String FAILED_QUERY_NOTIFICATION = "Failed query";
+    public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
+    public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
 
     protected static CompositeType SLOW_QUERY_TYPE; 
         
@@ -65,6 +65,10 @@
     
     protected static AtomicLong notifySequence = new AtomicLong(0);
     
+    protected boolean notifyPool = true;
+    
+    protected ConnectionPool pool = null;
+    
     protected static CompositeType getCompositeType() {
         if (SLOW_QUERY_TYPE==null) {
             try {
@@ -85,7 +89,10 @@
     public void reset(ConnectionPool parent, PooledConnection con) {
         // TODO Auto-generated method stub
         super.reset(parent, con);
-        if (parent!=null) poolName = parent.getName(); 
+        if (parent!=null) {
+            poolName = parent.getName();
+            pool = parent;
+        }
     }
 
 
@@ -99,6 +106,7 @@
 
     @Override
     public void poolStarted(ConnectionPool pool) {
+        this.pool = pool;
         super.poolStarted(pool);
         this.poolName = pool.getName();
         registerJmx();
@@ -114,16 +122,23 @@
     protected void notifyJmx(String query, String type) {
         try {
             DynamicMBean mbean = mbeans.get(poolName);
-            if (mbean!=null && mbean instanceof BaseModelMBean) {
-                BaseModelMBean bmbean = (BaseModelMBean)mbean;
-                long sequence = notifySequence.incrementAndGet();
-                Notification notification = 
-                    new Notification(type, 
-                                     mbean, 
-                                     sequence, 
-                                     System.currentTimeMillis(),
-                                     query);
-                bmbean.sendNotification(notification);
+            long sequence = notifySequence.incrementAndGet();
+            
+            if (isNotifyPool()) {
+                if (this.pool!=null && this.pool.getJmxPool()!=null) {
+                    this.pool.getJmxPool().notify(type, query);
+                }
+            } else {
+                if (mbean!=null && mbean instanceof BaseModelMBean) {
+                    Notification notification = 
+                        new Notification(type, 
+                                         mbean, 
+                                         sequence, 
+                                         System.currentTimeMillis(),
+                                         query);
+                    BaseModelMBean bmbean = (BaseModelMBean)mbean;
+                    bmbean.sendNotification(notification);
+                }
             }
         } catch (RuntimeOperationsException e) {
             if (log.isDebugEnabled()) {
@@ -160,6 +175,16 @@
         return poolName;
     }
     
+    
+    
+    public boolean isNotifyPool() {
+        return notifyPool;
+    }
+
+    public void setNotifyPool(boolean notifyPool) {
+        this.notifyPool = notifyPool;
+    }
+
     /**
      * JMX operation - remove all stats for this connection pool
      */
@@ -205,7 +230,6 @@
                     registry.unregisterComponent(oname);
                     registry.removeManagedBean(managed);
                 }
-                
             }
         } catch (MalformedObjectNameException e) {
             log.warn("Jmx deregistration failed.",e);
@@ -217,7 +241,10 @@
     
     protected void registerJmx() {
         try {
-            if (getCompositeType()!=null) {
+            //only if we notify the pool itself
+            if (isNotifyPool()) {
+                
+            } else if (getCompositeType()!=null) {
                 ObjectName oname = new ObjectName(ConnectionPool.POOL_JMX_TYPE_PREFIX+"SlowQueryReport"+",name=" + poolName);
                 Registry registry = Registry.getRegistry(null, null);
                 registry.loadDescriptors(getClass().getPackage().getName(),getClass().getClassLoader());

Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java Wed Apr 15 04:58:06 2009
@@ -17,12 +17,15 @@
 /**
  * @author Filip Hanik
  */
+import java.util.Iterator;
 import java.util.Properties;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.management.MBeanNotificationInfo;
 import javax.management.Notification;
 import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -41,6 +44,11 @@
      * sequence for JMX notifications
      */
     protected AtomicInteger sequence = new AtomicInteger(0);
+    
+    /**
+     * Listeners that are local and interested in our notifications, no need for JMX
+     */
+    protected ConcurrentLinkedQueue<NotificationListener> listeners = new ConcurrentLinkedQueue<NotificationListener>(); 
 
     public ConnectionPool(org.apache.tomcat.jdbc.pool.ConnectionPool pool) {
         super();
@@ -62,6 +70,8 @@
     public static final String NOTIFY_INIT = "INIT FAILED";
     public static final String NOTIFY_CONNECT = "CONNECTION FAILED";
     public static final String NOTIFY_ABANDON = "CONNECTION ABANDONED";
+    public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
+    public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
     
     
     
@@ -76,7 +86,7 @@
     } 
     
     public static MBeanNotificationInfo[] getDefaultNotificationInfo() {
-        String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT, NOTIFY_ABANDON}; 
+        String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT, NOTIFY_ABANDON, SLOW_QUERY_NOTIFICATION, FAILED_QUERY_NOTIFICATION}; 
         String name = Notification.class.getName(); 
         String description = "A connection pool error condition was met."; 
         MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description); 
@@ -96,8 +106,11 @@
                     this,
                     sequence.incrementAndGet(),
                     System.currentTimeMillis(),
-                    message!=null?message:"");
+                    "["+type+"] "+message);
             sendNotification(n);
+            for (NotificationListener listener : listeners) {
+                listener.handleNotification(n,this);
+            }
             return true;
         }catch (Exception x) {
             if (log.isDebugEnabled()) {
@@ -108,6 +121,14 @@
         
     }
     
+    public void addListener(NotificationListener list) {
+        listeners.add(list);
+    }
+    
+    public boolean removeListener(NotificationListener list) {
+        return listeners.remove(list);
+    }
+    
     //=================================================================
     //       POOL STATS
     //=================================================================
@@ -127,6 +148,14 @@
     public boolean isPoolSweeperEnabled() {
         return pool.getPoolProperties().isPoolSweeperEnabled();
     }
+    
+    public int getNumIdle() {
+        return getIdle();
+    }
+    
+    public int getNumActive() {
+        return getNumActive();
+    }
 
     //=================================================================
     //       POOL OPERATIONS

Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java Wed Apr 15 04:58:06 2009
@@ -30,7 +30,11 @@
     public int getActive();
     
     public boolean isPoolSweeperEnabled();
-
+    
+    public int getNumIdle();
+    
+    public int getNumActive();
+    
     //=================================================================
     //       POOL OPERATIONS
     //=================================================================

Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml Wed Apr 15 04:58:06 2009
@@ -15,7 +15,7 @@
 -->
 <mbeans-descriptors>
 
-    <mbean          name="DiagnosticsPool"
+    <mbean        name="TomcatJDBCPool"
            description="Provides per diagnostic metrics and notifications for JDBC operations"
                 domain="tomcat"
                  group="jdbc"
@@ -36,11 +36,21 @@
                   type="java.lang.Integer"
              writeable="false"/>
 
+    <attribute    name="numIdle"
+           description="Same as the idle attribute"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
     <attribute    name="active"
            description="The number of established connections in the pool that are in use"
                   type="java.lang.Integer"
              writeable="false"/>
     
+    <attribute    name="numActive"
+           description="Same as the active attribute"
+                  type="java.lang.Integer"
+             writeable="false"/>
+
     <attribute    name="poolSweeperEnabled"
            description="Returns true if the pool has a background thread running"
                   type="java.lang.Boolean"
@@ -216,15 +226,6 @@
                   description="forces a validation of abandoned connections" 
                   impact="ACTION" 
                   returnType="void" />
-
-
-    <notification name="jdbc-diagnostic"
-                  description="Notification issued when the request diagnostic actions kick in" >
-      <notification-type>INIT FAILED</notification-type>
-      <notification-type>CONNECTION FAILED</notification-type>
-      <notification-type>CONNECTION ABANDONED</notification-type>
-    </notification>
-   
   </mbean>
 
 </mbeans-descriptors>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org