Source Code Cross Referenced for JDBCSampler.java in  » Testing » jakarta-jmeter » org » apache » jmeter » protocol » jdbc » sampler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » jakarta jmeter » org.apache.jmeter.protocol.jdbc.sampler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *   http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         * 
017:         */
018:
019:        package org.apache.jmeter.protocol.jdbc.sampler;
020:
021:        import java.lang.reflect.Field;
022:        import java.sql.CallableStatement;
023:        import java.sql.Connection;
024:        import java.sql.PreparedStatement;
025:        import java.sql.ResultSet;
026:        import java.sql.ResultSetMetaData;
027:        import java.sql.SQLException;
028:        import java.sql.Statement;
029:        import java.util.Collection;
030:        import java.util.HashMap;
031:        import java.util.Iterator;
032:        import java.util.LinkedHashMap;
033:        import java.util.Map;
034:
035:        import org.apache.jmeter.protocol.jdbc.config.DataSourceElement;
036:        import org.apache.jmeter.samplers.AbstractSampler;
037:        import org.apache.jmeter.samplers.Entry;
038:        import org.apache.jmeter.samplers.SampleResult;
039:        import org.apache.jmeter.testbeans.TestBean;
040:        import org.apache.jmeter.util.JMeterUtils;
041:        import org.apache.jorphan.collections.Data;
042:        import org.apache.jorphan.logging.LoggingManager;
043:        import org.apache.log.Logger;
044:
045:        /**
046:         * A sampler which understands JDBC database requests.
047:         * 
048:         */
049:        public class JDBCSampler extends AbstractSampler implements  TestBean {
050:            private static final Logger log = LoggingManager
051:                    .getLoggerForClass();
052:
053:            // This value is used for both the connection (perConnCache) and statement (preparedStatementMap) caches.
054:            // TODO - do they have to be the same size?
055:            private static final int MAX_ENTRIES = JMeterUtils.getPropDefault(
056:                    "jdbcsampler.cachesize", 200); // $NON-NLS-1$
057:
058:            // String used to indicate a null value
059:            private static final String NULL_MARKER = JMeterUtils
060:                    .getPropDefault("jdbcsampler.nullmarker", "]NULL["); // $NON-NLS-1$
061:
062:            private static final String INOUT = "INOUT"; // $NON-NLS-1$
063:
064:            private static final String OUT = "OUT"; // $NON-NLS-1$
065:
066:            private static final Map mapJdbcNameToInt;
067:
068:            static {
069:                // based on e291. Getting the Name of a JDBC Type from javaalmanac.com
070:                // http://javaalmanac.com/egs/java.sql/JdbcInt2Str.html
071:                mapJdbcNameToInt = new HashMap();
072:
073:                //Get all fields in java.sql.Types and store the corresponding int values
074:                Field[] fields = java.sql.Types.class.getFields();
075:                for (int i = 0; i < fields.length; i++) {
076:                    try {
077:                        String name = fields[i].getName();
078:                        Integer value = (Integer) fields[i].get(null);
079:                        mapJdbcNameToInt.put(name.toLowerCase(), value);
080:                    } catch (IllegalAccessException e) {
081:                        throw new RuntimeException(e); // should not happen
082:                    }
083:                }
084:            }
085:
086:            // Query types (used to communicate with GUI)
087:            // N.B. These must not be changed, as they are used in the JMX files
088:            static final String SELECT = "Select Statement"; // $NON-NLS-1$
089:            static final String UPDATE = "Update Statement"; // $NON-NLS-1$
090:            static final String CALLABLE = "Callable Statement"; // $NON-NLS-1$
091:            static final String PREPARED_SELECT = "Prepared Select Statement"; // $NON-NLS-1$
092:            static final String PREPARED_UPDATE = "Prepared Update Statement"; // $NON-NLS-1$
093:            static final String COMMIT = "Commit"; // $NON-NLS-1$
094:            static final String ROLLBACK = "Rollback"; // $NON-NLS-1$
095:            static final String AUTOCOMMIT_FALSE = "AutoCommit(false)"; // $NON-NLS-1$
096:            static final String AUTOCOMMIT_TRUE = "AutoCommit(true)"; // $NON-NLS-1$
097:
098:            private String query = ""; // $NON-NLS-1$
099:
100:            private String dataSource = ""; // $NON-NLS-1$
101:
102:            private String queryType = SELECT;
103:            private String queryArguments = ""; // $NON-NLS-1$
104:            private String queryArgumentsTypes = ""; // $NON-NLS-1$
105:
106:            /**
107:             *  Cache of PreparedStatements stored in a per-connection basis. Each entry of this 
108:             *  cache is another Map mapping the statement string to the actual PreparedStatement.
109:             *  The cache has a fixed size of MAX_ENTRIES and it will throw aways all PreparedStatements 
110:             *  from the least recently used connections.  
111:             */
112:            private static Map perConnCache = new LinkedHashMap(MAX_ENTRIES) {
113:                private static final long serialVersionUID = 1L;
114:
115:                protected boolean removeEldestEntry(java.util.Map.Entry arg0) {
116:                    if (size() > MAX_ENTRIES) {
117:                        final Object value = arg0.getValue();
118:                        if (value instanceof  Map) {
119:                            closeAllStatements(((Map) value).values());
120:                        }
121:                        return true;
122:                    }
123:                    return false;
124:                }
125:            };
126:
127:            /**
128:             * Creates a JDBCSampler.
129:             */
130:            public JDBCSampler() {
131:            }
132:
133:            public SampleResult sample(Entry e) {
134:                log.debug("sampling jdbc");
135:
136:                SampleResult res = new SampleResult();
137:                res.setSampleLabel(getName());
138:                res.setSamplerData(toString());
139:                res.setDataType(SampleResult.TEXT);
140:                // Bug 31184 - make sure encoding is specified
141:                res.setDataEncoding(System.getProperty("file.encoding")); // $NON-NLS-1$
142:
143:                // Assume we will be successful
144:                res.setSuccessful(true);
145:
146:                res.sampleStart();
147:                Connection conn = null;
148:                Statement stmt = null;
149:
150:                try {
151:
152:                    try {
153:                        conn = DataSourceElement.getConnection(getDataSource());
154:                    } finally {
155:                        res.latencyEnd(); // use latency to measure connection time
156:                    }
157:                    res.setResponseHeaders(conn.toString());
158:
159:                    // Based on query return value, get results
160:                    String _queryType = getQueryType();
161:                    if (SELECT.equals(_queryType)) {
162:                        stmt = conn.createStatement();
163:                        ResultSet rs = null;
164:                        try {
165:                            rs = stmt.executeQuery(getQuery());
166:                            Data data = getDataFromResultSet(rs);
167:                            res.setResponseData(data.toString().getBytes());
168:                        } finally {
169:                            close(rs);
170:                        }
171:                    } else if (CALLABLE.equals(_queryType)) {
172:                        CallableStatement cstmt = getCallableStatement(conn);
173:                        int out[] = setArguments(cstmt);
174:                        // A CallableStatement can return more than 1 ResultSets
175:                        // plus a number of update counts. 
176:                        boolean hasResultSet = cstmt.execute();
177:                        String sb = resultSetsToString(cstmt, hasResultSet, out);
178:                        res.setResponseData(sb.toString().getBytes());
179:                    } else if (UPDATE.equals(_queryType)) {
180:                        stmt = conn.createStatement();
181:                        stmt.executeUpdate(getQuery());
182:                        int updateCount = stmt.getUpdateCount();
183:                        String results = updateCount + " updates";
184:                        res.setResponseData(results.getBytes());
185:                    } else if (PREPARED_SELECT.equals(_queryType)) {
186:                        PreparedStatement pstmt = getPreparedStatement(conn);
187:                        setArguments(pstmt);
188:                        pstmt.executeQuery();
189:                        String sb = resultSetsToString(pstmt, true, null);
190:                        res.setResponseData(sb.toString().getBytes());
191:                    } else if (PREPARED_UPDATE.equals(_queryType)) {
192:                        PreparedStatement pstmt = getPreparedStatement(conn);
193:                        setArguments(pstmt);
194:                        pstmt.executeUpdate();
195:                        String sb = resultSetsToString(pstmt, false, null);
196:                        res.setResponseData(sb.toString().getBytes());
197:                    } else if (ROLLBACK.equals(_queryType)) {
198:                        conn.rollback();
199:                        res.setResponseData(ROLLBACK.getBytes());
200:                    } else if (COMMIT.equals(_queryType)) {
201:                        conn.commit();
202:                        res.setResponseData(COMMIT.getBytes());
203:                    } else if (AUTOCOMMIT_FALSE.equals(_queryType)) {
204:                        conn.setAutoCommit(false);
205:                        res.setResponseData(AUTOCOMMIT_FALSE.getBytes());
206:                    } else if (AUTOCOMMIT_TRUE.equals(_queryType)) {
207:                        conn.setAutoCommit(true);
208:                        res.setResponseData(AUTOCOMMIT_TRUE.getBytes());
209:                    } else { // User provided incorrect query type
210:                        String results = "Unexpected query type: " + _queryType;
211:                        res.setResponseMessage(results);
212:                        res.setSuccessful(false);
213:                    }
214:
215:                } catch (SQLException ex) {
216:                    final String errCode = Integer.toString(ex.getErrorCode());
217:                    res.setResponseMessage(ex.toString());
218:                    res.setResponseCode(ex.getSQLState() + " " + errCode);
219:                    res.setSuccessful(false);
220:                } finally {
221:                    close(stmt);
222:                    close(conn);
223:                }
224:
225:                // TODO: process warnings? Set Code and Message to success?
226:                res.sampleEnd();
227:                return res;
228:            }
229:
230:            private String resultSetsToString(PreparedStatement pstmt,
231:                    boolean result, int[] out) throws SQLException {
232:                StringBuffer sb = new StringBuffer();
233:                sb.append("\n"); // $NON-NLS-1$
234:                int updateCount = 0;
235:                if (!result) {
236:                    updateCount = pstmt.getUpdateCount();
237:                }
238:                do {
239:                    if (result) {
240:                        ResultSet rs = null;
241:                        try {
242:                            rs = pstmt.getResultSet();
243:                            Data data = getDataFromResultSet(rs);
244:                            sb.append(data.toString()).append("\n"); // $NON-NLS-1$
245:                        } finally {
246:                            close(rs);
247:                        }
248:                    } else {
249:                        sb.append(updateCount).append(" updates.\n");
250:                    }
251:                    result = pstmt.getMoreResults();
252:                    if (!result) {
253:                        updateCount = pstmt.getUpdateCount();
254:                    }
255:                } while (result || (updateCount != -1));
256:                if (out != null && pstmt instanceof  CallableStatement) {
257:                    CallableStatement cs = (CallableStatement) pstmt;
258:                    sb.append("Output variables by position:\n");
259:                    for (int i = 0; i < out.length; i++) {
260:                        if (out[i] != java.sql.Types.NULL) {
261:                            sb.append("[");
262:                            sb.append(i + 1);
263:                            sb.append("] ");
264:                            sb.append(cs.getObject(i + 1));
265:                            sb.append("\n");
266:                        }
267:                    }
268:                }
269:                return sb.toString();
270:            }
271:
272:            private int[] setArguments(PreparedStatement pstmt)
273:                    throws SQLException {
274:                if (getQueryArguments().trim().length() == 0) {
275:                    return new int[] {};
276:                }
277:                String[] arguments = getQueryArguments().split(","); // $NON-NLS-1$
278:                String[] argumentsTypes = getQueryArgumentsTypes().split(","); // $NON-NLS-1$
279:                if (arguments.length != argumentsTypes.length) {
280:                    throw new SQLException("number of arguments ("
281:                            + arguments.length + ") and number of types ("
282:                            + argumentsTypes.length + ") are not equal");
283:                }
284:                int[] outputs = new int[arguments.length];
285:                for (int i = 0; i < arguments.length; i++) {
286:                    String argument = arguments[i];
287:                    String argumentType = argumentsTypes[i];
288:                    String[] arg = argumentType.split(" ");
289:                    String inputOutput = "";
290:                    if (arg.length > 1) {
291:                        argumentType = arg[1];
292:                        inputOutput = arg[0];
293:                    }
294:                    int targetSqlType = getJdbcType(argumentType);
295:                    try {
296:                        if (!OUT.equalsIgnoreCase(inputOutput)) {
297:                            if (argument.equals(NULL_MARKER)) {
298:                                pstmt.setNull(i + 1, targetSqlType);
299:                            } else {
300:                                pstmt.setObject(i + 1, argument, targetSqlType);
301:                            }
302:                        }
303:                        if (OUT.equalsIgnoreCase(inputOutput)
304:                                || INOUT.equalsIgnoreCase(inputOutput)) {
305:                            CallableStatement cs = (CallableStatement) pstmt;
306:                            cs.registerOutParameter(i + 1, targetSqlType);
307:                            outputs[i] = targetSqlType;
308:                        } else {
309:                            outputs[i] = java.sql.Types.NULL; // can't have an output parameter type null
310:                        }
311:                    } catch (NullPointerException e) { // thrown by Derby JDBC (at least) if there are no "?" markers in statement
312:                        throw new SQLException("Could not set argument no: "
313:                                + (i + 1) + " - missing parameter marker?");
314:                    }
315:                }
316:                return outputs;
317:            }
318:
319:            private static int getJdbcType(String jdbcType) throws SQLException {
320:                Integer entry = (Integer) mapJdbcNameToInt.get(jdbcType
321:                        .toLowerCase());
322:                if (entry == null) {
323:                    throw new SQLException("Invalid data type: " + jdbcType);
324:                }
325:                return (entry).intValue();
326:            }
327:
328:            private CallableStatement getCallableStatement(Connection conn)
329:                    throws SQLException {
330:                return (CallableStatement) getPreparedStatement(conn, true);
331:
332:            }
333:
334:            private PreparedStatement getPreparedStatement(Connection conn)
335:                    throws SQLException {
336:                return getPreparedStatement(conn, false);
337:            }
338:
339:            private PreparedStatement getPreparedStatement(Connection conn,
340:                    boolean callable) throws SQLException {
341:                Map preparedStatementMap = (Map) perConnCache.get(conn);
342:                if (null == preparedStatementMap) {
343:                    // MRU PreparedStatements cache. 
344:                    preparedStatementMap = new LinkedHashMap(MAX_ENTRIES) {
345:                        protected boolean removeEldestEntry(
346:                                java.util.Map.Entry arg0) {
347:                            final int theSize = size();
348:                            if (theSize > MAX_ENTRIES) {
349:                                Object value = arg0.getValue();
350:                                if (value instanceof  PreparedStatement) {
351:                                    PreparedStatement pstmt = (PreparedStatement) value;
352:                                    close(pstmt);
353:                                }
354:                                return true;
355:                            }
356:                            return false;
357:                        }
358:                    };
359:                    perConnCache.put(conn, preparedStatementMap);
360:                }
361:                PreparedStatement pstmt = (PreparedStatement) preparedStatementMap
362:                        .get(getQuery());
363:                if (null == pstmt) {
364:                    if (callable) {
365:                        pstmt = conn.prepareCall(getQuery());
366:                    } else {
367:                        pstmt = conn.prepareStatement(getQuery());
368:                    }
369:                    preparedStatementMap.put(getQuery(), pstmt);
370:                }
371:                pstmt.clearParameters();
372:                return pstmt;
373:            }
374:
375:            private static void closeAllStatements(Collection collection) {
376:                Iterator iterator = collection.iterator();
377:                while (iterator.hasNext()) {
378:                    PreparedStatement pstmt = (PreparedStatement) iterator
379:                            .next();
380:                    close(pstmt);
381:                }
382:            }
383:
384:            /**
385:             * Gets a Data object from a ResultSet.
386:             * 
387:             * @param rs
388:             *            ResultSet passed in from a database query
389:             * @return a Data object
390:             * @throws java.sql.SQLException
391:             */
392:            private Data getDataFromResultSet(ResultSet rs) throws SQLException {
393:                ResultSetMetaData meta = rs.getMetaData();
394:                Data data = new Data();
395:
396:                int numColumns = meta.getColumnCount();
397:                String[] dbCols = new String[numColumns];
398:                for (int i = 0; i < numColumns; i++) {
399:                    dbCols[i] = meta.getColumnName(i + 1);
400:                    data.addHeader(dbCols[i]);
401:                }
402:
403:                while (rs.next()) {
404:                    data.next();
405:                    for (int i = 0; i < numColumns; i++) {
406:                        Object o = rs.getObject(i + 1);
407:                        if (o instanceof  byte[]) {
408:                            o = new String((byte[]) o);
409:                        }
410:                        data.addColumnValue(dbCols[i], o);
411:                    }
412:                }
413:                return data;
414:            }
415:
416:            public static void close(Connection c) {
417:                try {
418:                    if (c != null)
419:                        c.close();
420:                } catch (SQLException e) {
421:                    log.warn("Error closing Connection", e);
422:                }
423:            }
424:
425:            public static void close(Statement s) {
426:                try {
427:                    if (s != null)
428:                        s.close();
429:                } catch (SQLException e) {
430:                    log.warn("Error closing Statement " + s.toString(), e);
431:                }
432:            }
433:
434:            public static void close(ResultSet rs) {
435:                try {
436:                    if (rs != null)
437:                        rs.close();
438:                } catch (SQLException e) {
439:                    log.warn("Error closing ResultSet", e);
440:                }
441:            }
442:
443:            public String getQuery() {
444:                return query;
445:            }
446:
447:            public String toString() {
448:                StringBuffer sb = new StringBuffer(80);
449:                sb.append("["); // $NON-NLS-1$
450:                sb.append(getQueryType());
451:                sb.append("] "); // $NON-NLS-1$
452:                sb.append(getQuery());
453:                return sb.toString();
454:            }
455:
456:            /**
457:             * @param query
458:             *            The query to set.
459:             */
460:            public void setQuery(String query) {
461:                this .query = query;
462:            }
463:
464:            /**
465:             * @return Returns the dataSource.
466:             */
467:            public String getDataSource() {
468:                return dataSource;
469:            }
470:
471:            /**
472:             * @param dataSource
473:             *            The dataSource to set.
474:             */
475:            public void setDataSource(String dataSource) {
476:                this .dataSource = dataSource;
477:            }
478:
479:            /**
480:             * @return Returns the queryType.
481:             */
482:            public String getQueryType() {
483:                return queryType;
484:            }
485:
486:            /**
487:             * @param queryType The queryType to set.
488:             */
489:            public void setQueryType(String queryType) {
490:                this .queryType = queryType;
491:            }
492:
493:            public String getQueryArguments() {
494:                return queryArguments;
495:            }
496:
497:            public void setQueryArguments(String queryArguments) {
498:                this .queryArguments = queryArguments;
499:            }
500:
501:            public String getQueryArgumentsTypes() {
502:                return queryArgumentsTypes;
503:            }
504:
505:            public void setQueryArgumentsTypes(String queryArgumentsType) {
506:                this.queryArgumentsTypes = queryArgumentsType;
507:            }
508:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.