View Javadoc

1   /*
2    * Copyright 2010-2012 Julien Nicoulaud <julien.nicoulaud@gmail.com>
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.dbcp;
17  
18  import org.weakref.jmx.MBeanExporter;
19  import org.weakref.jmx.Managed;
20  
21  import javax.management.MBeanServer;
22  import java.lang.management.ManagementFactory;
23  import java.sql.SQLException;
24  import java.util.UUID;
25  
26  /**
27   * Wrapper for {@link BasicDataSource} that exposes some fields and methods as a MBean.
28   *
29   * @author <a href="mailto:julien.nicoulaud@gmail.com">Julien Nicoulaud</a>
30   * @since 0.1
31   */
32  public class ManagedBasicDataSource extends BasicDataSource {
33  
34      /**
35       * The default auto-generated unique name for the exposed MBean.
36       */
37      public static final String DEFAULT_MBEAN_NAME = "org.apache.commons.dbcp:ManagedBasicDataSource=ManagedBasicDataSource";
38  
39      /**
40       * The name under which this object is exposed to the MBean server.
41       */
42      protected final String mBeanName;
43  
44      /**
45       * Build a new instance of {@link org.apache.commons.dbcp.ManagedBasicDataSource} and expose it as a MBean with an auto-generated unique name.
46       *
47       * @see #DEFAULT_MBEAN_NAME
48       * @see #exportMBean(MBeanServer, String)
49       */
50      public ManagedBasicDataSource() {
51          this(DEFAULT_MBEAN_NAME + "-" + UUID.randomUUID());
52      }
53  
54      /**
55       * Build a new instance of {@link org.apache.commons.dbcp.ManagedBasicDataSource} and expose it as a MBean with the specified name.
56       *
57       * @param mBeanName the name of the MBean to expose, should be unique accross the target application.
58       * @see #DEFAULT_MBEAN_NAME
59       * @see #exportMBean(MBeanServer, String)
60       */
61      public ManagedBasicDataSource(String mBeanName) {
62          this.mBeanName = mBeanName;
63          exportMBean(ManagementFactory.getPlatformMBeanServer(), mBeanName);
64      }
65  
66      /**
67       * Build a new instance of {@link org.apache.commons.dbcp.ManagedBasicDataSource} and expose it as a MBean with the specified name.
68       *
69       *
70       * @param mBeanServer
71       * @param mBeanName the name of the MBean to expose, should be unique accross the target application.
72       * @see #DEFAULT_MBEAN_NAME
73       * @see #exportMBean(MBeanServer, String)
74       */
75      public ManagedBasicDataSource(MBeanServer mBeanServer, String mBeanName) {
76          this.mBeanName = mBeanName;
77          exportMBean(mBeanServer, mBeanName);
78      }
79  
80      /**
81       * Export this object as a MBean to the platform default MBean server.
82       *
83       * @param mBeanServer
84       * @param name the name of the MBean to expose.
85       */
86      protected synchronized void exportMBean(MBeanServer mBeanServer, String name) {
87          new MBeanExporter(mBeanServer).export(name, this);
88      }
89  
90      /**
91       * Get the name under which this object is exposed to the MBean server.
92       *
93       * @return the MBean object name.
94       */
95      public String getMBeanName() {
96          return mBeanName;
97      }
98  
99      /**
100      * {@inheritDoc}
101      */
102     @Override
103     public boolean isWrapperFor(Class<?> iface) throws SQLException {
104         return iface.isInstance(this);
105     }
106 
107     /**
108      * {@inheritDoc}
109      */
110     @Override
111     public <T> T unwrap(Class<T> iface) throws SQLException {
112         if (isWrapperFor(iface)) {
113             return iface.cast(this);
114         }
115         return super.unwrap(iface);
116     }
117 
118     /**
119      * Get the current number of active connections that have been allocated from this data source.
120      *
121      * @return the current number of active connections.
122      */
123     @Managed(description = "The current number of active connections that have been allocated from this data source.")
124     public synchronized int getNumActive() {
125         return super.getNumActive();
126     }
127 
128     /**
129      * Get the current number of idle connections that are waiting to be allocated from this data source.
130      *
131      * @return the current number of idle connections.
132      */
133     @Managed(description = "The current number of idle connections that are waiting to be allocated from this data source.")
134     public synchronized int getNumIdle() {
135         return super.getNumIdle();
136     }
137 
138     /**
139      * Get the maximum number of active connections that can be allocated at the same time.
140      * <p/>
141      * <p>A negative number means that there is no limit.</p>
142      *
143      * @return the maximum number of active connections.
144      */
145     @Managed(description = "The maximum number of active connections that can be allocated at the same time.")
146     public synchronized int getMaxActive() {
147         return super.getMaxActive();
148     }
149 
150     /**
151      * Set the maximum number of active connections that can be allocated at the same time. Use a negative value for no limit.
152      *
153      * @param maxActive the new value for maxActive.
154      * @see #getMaxActive()
155      */
156     @Managed(description = "Set the maximum number of active connections that can be allocated at the same time. Use a negative value for no limit.")
157     public synchronized void setMaxActive(int maxActive) {
158         super.setMaxActive(maxActive);
159     }
160 
161     /**
162      * Get the maximum number of connections that can remain idle in the pool.
163      * <p/>
164      * <p>A negative value indicates that there is no limit.</p>
165      *
166      * @return the maximum number of idle connections.
167      */
168     @Managed(description = "The maximum number of connections that can remain idle in the pool.")
169     public synchronized int getMaxIdle() {
170         return super.getMaxIdle();
171     }
172 
173     /**
174      * Set the maximum number of connections that can remain idle in the pool.
175      *
176      * @param maxIdle the new value for maxIdle.
177      * @see #getMaxIdle()
178      */
179     @Managed(description = "Set the maximum number of connections that can remain idle in the pool.")
180     public synchronized void setMaxIdle(int maxIdle) {
181         super.setMaxIdle(maxIdle);
182     }
183 
184     /**
185      * Get the minimum number of idle connections in the pool.
186      *
187      * @return the minimum number of idle connections.
188      * @see org.apache.commons.pool.impl.GenericObjectPool#getMinIdle()
189      */
190     @Managed(description = "The minimum number of idle connections in the pool.")
191     public synchronized int getMinIdle() {
192         return super.getMinIdle();
193     }
194 
195     /**
196      * Set the minimum number of idle connections in the pool.
197      *
198      * @param minIdle the new value for minIdle.
199      * @see org.apache.commons.pool.impl.GenericObjectPool#setMinIdle(int)
200      */
201     @Managed(description = "The minimum number of idle connections in the pool.")
202     public synchronized void setMinIdle(int minIdle) {
203         super.setMinIdle(minIdle);
204     }
205 
206     /**
207      * Get the maximum number of milliseconds that the pool will wait for a connection to be returned before throwing an exception.
208      * <p/>
209      * <p>A value less than or equal to zero means the pool is set to wait indefinitely.</p>
210      *
211      * @return the maxWait property value.
212      */
213     @Managed(description = "The maximum number of milliseconds that the pool will wait for a connection to be returned before throwing an exception.")
214     public synchronized long getMaxWait() {
215         return super.getMaxWait();
216     }
217 
218     /**
219      * Set the maxWait property.
220      * <p/>
221      * <p>Use -1 to make the pool wait indefinitely.</p>
222      *
223      * @param maxWait the new value for maxWait.
224      * @see #getMaxWait()
225      */
226     @Managed(description = "Set the maxWait property. Use -1 to make the pool wait indefinitely.")
227     public synchronized void setMaxWait(long maxWait) {
228         super.setMaxWait(maxWait);
229     }
230 
231     /**
232      * Get the JDBC connection {@link #url} property.
233      *
234      * @return the {@link #url} passed to the JDBC driver to establish connections.
235      */
236     @Managed
237     public synchronized String getUrl() {
238         return super.getUrl();
239     }
240 
241     /**
242      * Get the JDBC connection {@link #username} property.
243      *
244      * @return the {@link #username} passed to the JDBC driver to establish connections.
245      */
246     @Managed
247     public String getUsername() {
248         return super.getUsername();
249     }
250 }