Author: markt
Date: Thu Feb 13 08:59:20 2014
New Revision: 1567866

URL: http://svn.apache.org/r1567866
Log:
First pass at fixing DBCP-219
Expose PoolableConnections via JMX creating an hierarchy 
pool->connection->statementpool

Added:
    
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionMXBean.java
   (with props)
Modified:
    
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
    
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java

Modified: 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
URL: 
http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java?rev=1567866&r1=1567865&r2=1567866&view=diff
==============================================================================
--- 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
 (original)
+++ 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
 Thu Feb 13 08:59:20 2014
@@ -18,6 +18,7 @@ package org.apache.commons.dbcp2;
 
 import java.sql.Connection;
 import java.sql.SQLException;
+
 import org.apache.commons.pool2.ObjectPool;
 
 /**
@@ -30,7 +31,9 @@ import org.apache.commons.pool2.ObjectPo
  * @author James House
  * @version $Revision$ $Date$
  */
-public class PoolableConnection extends DelegatingConnection<Connection> {
+public class PoolableConnection extends DelegatingConnection<Connection>
+        implements PoolableConnectionMXBean {
+
     /** The pool to which I should return. */
     private ObjectPool<PoolableConnection> _pool = null;
 
@@ -135,8 +138,19 @@ public class PoolableConnection extends 
     /**
      * Actually close my underlying {@link Connection}.
      */
+    @Override
     public void reallyClose() throws SQLException {
         super.closeInternal();
     }
+
+
+    /**
+     * Expose the {@link #toString()} method via a bean getter so it can be 
read
+     * as a property via JMX.
+     */
+    @Override
+    public String getToString() {
+        return toString();
+    }
 }
 

Modified: 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java?rev=1567866&r1=1567865&r2=1567866&view=diff
==============================================================================
--- 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
 (original)
+++ 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
 Thu Feb 13 08:59:20 2014
@@ -17,12 +17,19 @@
 
 package org.apache.commons.dbcp2;
 
+import java.lang.management.ManagementFactory;
 import java.sql.Connection;
 import java.sql.Statement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Collection;
+import java.util.concurrent.atomic.AtomicLong;
 
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
 
 import org.apache.commons.logging.Log;
@@ -51,6 +58,8 @@ public class PoolableConnectionFactory
     private static final Log log =
             LogFactory.getLog(PoolableConnectionFactory.class);
 
+    private static MBeanServer MBEAN_SERVER = 
ManagementFactory.getPlatformMBeanServer();
+
     /**
      * Create a new <tt>PoolableConnectionFactory</tt>.
      * @param connFactory the {@link ConnectionFactory} from which to obtain
@@ -190,6 +199,9 @@ public class PoolableConnectionFactory
             // Rethrow original exception so it is visible to caller
             throw sqle;
         }
+
+        long connIndex = connectionIndex.getAndIncrement();
+
         if(poolStatements) {
             conn = new PoolingConnection(conn);
             GenericKeyedObjectPoolConfig config = new 
GenericKeyedObjectPoolConfig();
@@ -200,16 +212,37 @@ public class PoolableConnectionFactory
             config.setMaxTotal(maxOpenPreparedStatements);
             if (dataSourceJmxName != null) {
                 StringBuilder base = new 
StringBuilder(dataSourceJmxName.toString());
-                base.append(",pool=statements,connection=");
+                base.append(",connection=");
                 config.setJmxNameBase(base.toString());
-                config.setJmxNamePrefix(Integer.toString(conn.hashCode()));
+                config.setJmxNamePrefix(Long.toString(connIndex) + 
",pool=statements");
             }
             KeyedObjectPool<PStmtKey,DelegatingPreparedStatement> stmtPool =
                     new GenericKeyedObjectPool<>((PoolingConnection)conn, 
config);
             ((PoolingConnection)conn).setStatementPool(stmtPool);
             ((PoolingConnection) conn).setCacheState(_cacheState);
         }
-        return new DefaultPooledObject<>(new PoolableConnection(conn,_pool));
+
+        PoolableConnection pc = new PoolableConnection(conn,_pool);
+
+        // Register this connection with JMX
+        if (dataSourceJmxName != null) {
+            StringBuilder connectionJmxName = new 
StringBuilder(dataSourceJmxName.toString());
+            connectionJmxName.append(",connection=");
+            connectionJmxName.append(connIndex);
+            jmxRegister(pc, connectionJmxName.toString());
+        }
+
+        return new DefaultPooledObject<>(pc);
+    }
+
+    private void jmxRegister(PoolableConnection pc, String jmxName) {
+        try {
+            ObjectName oName = new ObjectName(jmxName);
+            MBEAN_SERVER.registerMBean(pc, oName);
+        } catch (MalformedObjectNameException | InstanceAlreadyExistsException 
|
+                MBeanRegistrationException | NotCompliantMBeanException e) {
+            // For now, simply skip registration
+        }
     }
 
     protected void initializeConnection(Connection conn) throws SQLException {
@@ -380,6 +413,7 @@ public class PoolableConnectionFactory
     private int maxOpenPreparedStatements =
         GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL_PER_KEY;
     private long maxConnLifetimeMillis = -1;
+    private AtomicLong connectionIndex = new AtomicLong(0);
 
     /**
      * Internal constant to indicate the level is not set.

Added: 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionMXBean.java
URL: 
http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionMXBean.java?rev=1567866&view=auto
==============================================================================
--- 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionMXBean.java
 (added)
+++ 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionMXBean.java
 Thu Feb 13 08:59:20 2014
@@ -0,0 +1,58 @@
+/*
+ * 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.commons.dbcp2;
+
+import java.sql.SQLException;
+
+/**
+ * Defines the attributes and methods that will be exposed via JMX for
+ * {@link PoolableConnection} instances.
+ */
+public interface PoolableConnectionMXBean {
+    // Read-only properties
+    boolean isClosed() throws SQLException;
+    //SQLWarning getWarnings() throws SQLException;
+    String getToString();
+
+    // Read-write properties
+    boolean getAutoCommit() throws SQLException;
+    void setAutoCommit(boolean autoCommit) throws SQLException;
+
+    boolean getCacheState();
+    void setCacheState(boolean cacheState);
+
+    String getCatalog() throws SQLException;
+    void setCatalog(String catalog) throws SQLException;
+
+    int getHoldability() throws SQLException;
+    void setHoldability(int holdability) throws SQLException;
+
+    boolean isReadOnly() throws SQLException;
+    void setReadOnly(boolean readOnly) throws SQLException;
+
+    String getSchema() throws SQLException;
+    void setSchema(String schema) throws SQLException;
+
+    int getTransactionIsolation() throws SQLException;
+    void setTransactionIsolation(int level) throws SQLException;
+
+    // Methods
+    void clearCachedState();
+    void clearWarnings() throws SQLException;
+    void close() throws SQLException;
+    void reallyClose() throws SQLException;
+}

Propchange: 
commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/PoolableConnectionMXBean.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to