KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jmeter > protocol > jdbc > sampler > JDBCSampler


1 // $Header: /home/cvs/jakarta-jmeter/src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSampler.java,v 1.27.2.2 2004/10/17 16:01:38 sebb Exp $
2
/*
3  * Copyright 2001-2004 The Apache Software Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17 */

18
19 package org.apache.jmeter.protocol.jdbc.sampler;
20
21 import java.io.IOException JavaDoc;
22 import java.io.NotActiveException JavaDoc;
23 import java.io.ObjectInputStream JavaDoc;
24 import java.sql.Connection JavaDoc;
25 import java.sql.ResultSet JavaDoc;
26 import java.sql.ResultSetMetaData JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import java.sql.Statement JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Map JavaDoc;
31
32 import org.apache.jmeter.config.ConfigTestElement;
33 import org.apache.jmeter.engine.event.LoopIterationEvent;
34 import org.apache.jmeter.protocol.jdbc.util.ConnectionPoolException;
35 import org.apache.jmeter.protocol.jdbc.util.DBConnectionManager;
36 import org.apache.jmeter.protocol.jdbc.util.DBKey;
37 import org.apache.jmeter.samplers.AbstractSampler;
38 import org.apache.jmeter.samplers.Entry;
39 import org.apache.jmeter.samplers.SampleResult;
40 import org.apache.jmeter.testelement.TestListener;
41 import org.apache.jmeter.testelement.property.JMeterProperty;
42 import org.apache.jmeter.testelement.property.PropertyIterator;
43 import org.apache.jorphan.collections.Data;
44 import org.apache.jorphan.logging.LoggingManager;
45 import org.apache.log.Logger;
46
47 /**
48  * A sampler which understands JDBC database requests.
49  *
50  * @author Original author unknown
51  * @author <a HREF="mailto:jeremy_a@bigfoot.com">Jeremy Arnold</a>
52  * @version $Revision: 1.27.2.2 $
53  */

54 public class JDBCSampler extends AbstractSampler implements TestListener
55 {
56     private static Logger log = LoggingManager.getLoggerForClass();
57     
58     public static final String JavaDoc URL = "JDBCSampler.url";
59     public static final String JavaDoc DRIVER = "JDBCSampler.driver";
60     public static final String JavaDoc QUERY = "JDBCSampler.query";
61
62     public static final String JavaDoc JDBCSAMPLER_PROPERTY_PREFIX = "JDBCSampler.";
63     public static final String JavaDoc CONNECTION_POOL_IMPL =
64         JDBCSAMPLER_PROPERTY_PREFIX + "connPoolClass";
65
66     
67     /** Database connection pool manager. */
68     private transient DBConnectionManager manager =
69         DBConnectionManager.getManager();
70     private transient DBKey dbkey = null;
71
72     /**
73      * Creates a JDBCSampler.
74      */

75     public JDBCSampler()
76     {
77     }
78
79     // Resolve the transient manager object
80
private void readObject(ObjectInputStream JavaDoc is)
81     throws NotActiveException JavaDoc, IOException JavaDoc, ClassNotFoundException JavaDoc
82     {
83         is.defaultReadObject();
84         manager = DBConnectionManager.getManager();
85     }
86     
87     public SampleResult sample(Entry e)
88     {
89         DBKey key = null;
90
91         SampleResult res = new SampleResult();
92         res.setSampleLabel(getName());
93         res.setSamplerData(this.toString());
94
95
96         res.sampleStart();
97         Connection JavaDoc conn = null;
98         Statement JavaDoc stmt = null;
99
100         try
101         {
102             key = getKey();
103             
104             // TODO: Consider creating a sub-result with the time to get the
105
// connection.
106
conn = manager.getConnection(key);
107             stmt = conn.createStatement();
108             
109             // Based on query return value, get results
110
if (stmt.execute(getQuery()))
111             {
112                 ResultSet JavaDoc rs = null;
113                 try
114                 {
115                     rs = stmt.getResultSet();
116                     Data JavaDoc data = getDataFromResultSet(rs);
117                     res.setResponseData(data.toString().getBytes());
118                 }
119                 finally
120                 {
121                     if (rs != null)
122                     {
123                         try
124                         {
125                             rs.close();
126                         }
127                         catch (SQLException JavaDoc exc)
128                         {
129                             log.warn("Error closing ResultSet", exc);
130                         }
131                     }
132                 }
133             }
134             else
135             {
136                 int updateCount = stmt.getUpdateCount();
137                 String JavaDoc results = updateCount + " updates";
138                 res.setResponseData(results.getBytes());
139             }
140
141             res.setDataType(SampleResult.TEXT);
142             res.setSuccessful(true);
143         }
144         catch (Exception JavaDoc ex)
145         {
146             log.error("Error in JDBC sampling", ex);
147             res.setResponseMessage(ex.toString());
148             res.setResponseData(new byte[0]);
149             res.setSuccessful(false);
150         }
151         finally
152         {
153             if (stmt != null)
154             {
155                 try
156                 {
157                     stmt.close();
158                 }
159                 catch (SQLException JavaDoc err)
160                 {
161                     stmt = null;
162                 }
163             }
164
165             if (conn != null)
166             {
167                 manager.releaseConnection(key, conn);
168             }
169         }
170
171         res.sampleEnd();
172         return res;
173     }
174
175     private synchronized DBKey getKey() throws ConnectionPoolException
176     {
177         if (dbkey == null)
178         {
179             // With multiple threads, it is possible that more than one thread
180
// will enter this block at the same time, resulting in multiple
181
// calls to manager.getKey(). But this is okay, since DBKey has
182
// a proper implementation of equals and hashCode. The original
183
// implementation of this method always returned a new instance --
184
// this cached dbkey is just a performance optimization.
185
dbkey =
186                 manager.getKey(
187                     getUrl(),
188                     getUsername(),
189                     getPassword(),
190                     getDriver(),
191                     getJDBCProperties());
192         }
193         
194         return dbkey;
195     }
196
197     private Map JavaDoc getJDBCProperties()
198     {
199         Map JavaDoc props = new HashMap JavaDoc();
200         
201         PropertyIterator iter = propertyIterator();
202         while (iter.hasNext())
203         {
204             JMeterProperty prop = iter.next();
205             if (prop.getName().startsWith(JDBCSAMPLER_PROPERTY_PREFIX))
206             {
207                 props.put(prop.getName(), prop);
208             }
209         }
210         return props;
211     }
212     
213     /**
214      * Gets a Data object from a ResultSet.
215      *
216      * @param rs ResultSet passed in from a database query
217      * @return a Data object
218      * @throws java.sql.SQLException
219      */

220     private Data JavaDoc getDataFromResultSet(ResultSet JavaDoc rs) throws SQLException JavaDoc
221     {
222         ResultSetMetaData JavaDoc meta = rs.getMetaData();
223         Data JavaDoc data = new Data JavaDoc();
224
225         int numColumns = meta.getColumnCount();
226         String JavaDoc[] dbCols = new String JavaDoc[numColumns];
227         for (int i = 0; i < numColumns; i++)
228         {
229             dbCols[i] = meta.getColumnName(i + 1);
230             data.addHeader(dbCols[i]);
231         }
232         
233         while (rs.next())
234         {
235             data.next();
236             for (int i = 0; i < numColumns; i++)
237             {
238                 Object JavaDoc o = rs.getObject(i + 1);
239                 if (o instanceof byte[])
240                 {
241                     o = new String JavaDoc((byte[]) o);
242                 }
243                 data.addColumnValue(dbCols[i], o);
244             }
245         }
246         return data;
247     }
248
249
250     public String JavaDoc getDriver()
251     {
252         return getPropertyAsString(DRIVER);
253     }
254
255     public String JavaDoc getUrl()
256     {
257         return getPropertyAsString(URL);
258     }
259
260     public String JavaDoc getUsername()
261     {
262         return getPropertyAsString(ConfigTestElement.USERNAME);
263     }
264
265     public String JavaDoc getPassword()
266     {
267         return getPropertyAsString(ConfigTestElement.PASSWORD);
268     }
269
270     public String JavaDoc getQuery()
271     {
272         return this.getPropertyAsString(QUERY);
273     }
274
275
276     public String JavaDoc toString()
277     {
278         return getUrl() + ", user: " + getUsername() + "\n" + getQuery();
279     }
280
281
282     public void testStarted(String JavaDoc host)
283     {
284         testStarted();
285     }
286
287     public synchronized void testStarted()
288     {
289 /*
290  * Test started is called before the thread data has been set up, so cannot
291  * rely on its values being available.
292 */

293 // log.debug("testStarted(), thread: "+Thread.currentThread().getName());
294
// // The first call to getKey for a given key will set up the connection
295
// // pool. This can take awhile, so do it while the test is starting
296
// // instead of waiting for the first sample.
297
// try
298
// {
299
// getKey();
300
// }
301
// catch (ConnectionPoolException e)
302
// {
303
// log.error("Error initializing database connection", e);
304
// }
305
}
306
307     public void testEnded(String JavaDoc host)
308     {
309         testEnded();
310     }
311
312     public synchronized void testEnded()
313     {
314         log.debug("testEndded(), thread: "+Thread.currentThread().getName());
315         manager.shutdown();
316         dbkey = null;
317     }
318
319     public void testIterationStart(LoopIterationEvent event)
320     {
321     }
322 }
323
Popular Tags