You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by fs...@apache.org on 2016/09/20 18:55:08 UTC
svn commit: r1761614 - in /jmeter/trunk: bin/jmeter.properties
src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/AbstractJDBCTestElement.java
xdocs/changes.xml xdocs/usermanual/component_reference.xml
xdocs/usermanual/properties_reference.xml
Author: fschumacher
Date: Tue Sep 20 18:55:08 2016
New Revision: 1761614
URL: http://svn.apache.org/viewvc?rev=1761614&view=rev
Log:
Handle CLOBs and BLOBs and limit them if necessary when storing them in result sampler.
Bugzilla Id: 60085
Modified:
jmeter/trunk/bin/jmeter.properties
jmeter/trunk/src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/AbstractJDBCTestElement.java
jmeter/trunk/xdocs/changes.xml
jmeter/trunk/xdocs/usermanual/component_reference.xml
jmeter/trunk/xdocs/usermanual/properties_reference.xml
Modified: jmeter/trunk/bin/jmeter.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1761614&r1=1761613&r2=1761614&view=diff
==============================================================================
--- jmeter/trunk/bin/jmeter.properties (original)
+++ jmeter/trunk/bin/jmeter.properties Tue Sep 20 18:55:08 2016
@@ -829,6 +829,9 @@ wmlParser.types=text/vnd.wap.wml
# String used to indicate a null value
#jdbcsampler.nullmarker=]NULL[
+#
+# Max size of BLOBs and CLOBs to store in JDBC sampler. Result will be cut off
+#jdbcsampler.max_retain_result_size=65536
#---------------------------------------------------------------------------
# OS Process Sampler configuration
Modified: jmeter/trunk/src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/AbstractJDBCTestElement.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/AbstractJDBCTestElement.java?rev=1761614&r1=1761613&r2=1761614&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/AbstractJDBCTestElement.java (original)
+++ jmeter/trunk/src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/AbstractJDBCTestElement.java Tue Sep 20 18:55:08 2016
@@ -23,7 +23,9 @@ import java.io.UnsupportedEncodingExcept
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
+import java.sql.Blob;
import java.sql.CallableStatement;
+import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
@@ -35,11 +37,11 @@ import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.io.IOUtils;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.save.CSVSaveService;
import org.apache.jmeter.testelement.AbstractTestElement;
@@ -124,6 +126,8 @@ public abstract class AbstractJDBCTestEl
private String resultVariable = ""; // $NON-NLS-1$
private String queryTimeout = ""; // $NON-NLS-1$
+ private static final int MAX_RETAIN_SIZE = JMeterUtils.getPropDefault("jdbcsampler.max_retain_result_size", 64 * 1024);
+
/**
* Creates a JDBCSampler.
*/
@@ -283,16 +287,11 @@ public abstract class AbstractJDBCTestEl
if (name.length()>0){ // Save the value in the variable if present
Object o = outputValues.get(i);
if( o instanceof java.sql.ResultSet ) {
- ResultSet resultSet = (ResultSet) o;
- if(RS_STORE_AS_OBJECT.equals(resultSetHandler)) {
- jmvars.putObject(name, o);
- }
- else if( RS_COUNT_RECORDS.equals(resultSetHandler)) {
- jmvars.put(name,o.toString()+" "+countRows(resultSet)+" rows");
- }
- else {
- jmvars.put(name, o.toString());
- }
+ putIntoVar(jmvars, name, (java.sql.ResultSet) o);
+ } else if (o instanceof java.sql.Clob) {
+ putIntoVar(jmvars, name, (java.sql.Clob) o);
+ } else if (o instanceof java.sql.Blob) {
+ putIntoVar(jmvars, name, (java.sql.Blob) o);
}
else {
jmvars.put(name, o == null ? null : o.toString());
@@ -303,7 +302,59 @@ public abstract class AbstractJDBCTestEl
}
return sb.toString();
}
-
+
+ private void putIntoVar(final JMeterVariables jmvars, final String name,
+ final ResultSet resultSet) throws SQLException {
+ if (RS_STORE_AS_OBJECT.equals(resultSetHandler)) {
+ jmvars.putObject(name, resultSet);
+ } else if (RS_COUNT_RECORDS.equals(resultSetHandler)) {
+ jmvars.put(name, resultSet.toString() + " " + countRows(resultSet)
+ + " rows");
+ } else {
+ jmvars.put(name, resultSet.toString());
+ }
+ }
+
+ private void putIntoVar(final JMeterVariables jmvars, final String name,
+ final Clob clob) throws SQLException {
+ try {
+ if (clob.length() > MAX_RETAIN_SIZE) {
+ jmvars.put(
+ name,
+ IOUtils.toString(clob.getCharacterStream(0,
+ MAX_RETAIN_SIZE))
+ + "<result cut off, it is too big>");
+ } else {
+ jmvars.put(name, IOUtils.toString(clob.getCharacterStream()));
+ }
+ } catch (IOException e) {
+ log.warn("Could not read CLOB into " + name, e);
+ }
+ }
+
+ private void putIntoVar(final JMeterVariables jmvars, final String name,
+ final Blob blob) throws SQLException {
+ if (RS_STORE_AS_OBJECT.equals(resultSetHandler)) {
+ try {
+ long length = Math.max(blob.length(), MAX_RETAIN_SIZE);
+ jmvars.putObject(name,
+ IOUtils.toByteArray(blob.getBinaryStream(0, length)));
+ } catch (IOException e) {
+ log.warn("Could not read BLOB into " + name + " as object.", e);
+ }
+ } else if (RS_COUNT_RECORDS.equals(resultSetHandler)) {
+ jmvars.put(name, blob.length() + " bytes");
+ } else {
+ try {
+ long length = Math.max(blob.length(), MAX_RETAIN_SIZE);
+ jmvars.put(name, IOUtils.toString(
+ blob.getBinaryStream(0, length), ENCODING));
+ } catch (IOException e) {
+ log.warn("Can't convert BLOB to String using " + ENCODING, e);
+ }
+ }
+ }
+
/**
* Count rows in result set
* @param resultSet {@link ResultSet}
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1761614&r1=1761613&r2=1761614&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Tue Sep 20 18:55:08 2016
@@ -93,6 +93,7 @@ Summary
<ul>
<li><pr>211</pr>Differentiate the timing for JDBC Sampler. Use latency and connect time. Contributed by Thomas Peyrard (thomas.peyrard at murex.com)</li>
<li><bug>59620</bug>Fix button action in "JMS Publisher -> Random File from folder specified below" to allow to select a directory</li>
+ <li><bug>60085</bug>Handle CLOBs and BLOBs and limit them if necessary when storing them in result sampler.</li>
</ul>
<h3>Controllers</h3>
Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1761614&r1=1761613&r2=1761614&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/component_reference.xml Tue Sep 20 18:55:08 2016
@@ -593,9 +593,9 @@ the additional variables for rows four,
</property>
<property name="Handle ResultSet" required="No">Defines how ResultSet returned from callable statements be handled:
<ul>
- <li><code>Store As String</code> (default) - All variables on Variable Names list are stored as strings, will not iterate through a <code>ResultSet</code> when present on the list.</li>
- <li><code>Store As Object</code> - Variables of <code>ResultSet</code> type on Variables Names list will be stored as Object and can be accessed in subsequent tests/scripts and iterated, will not iterate through the <code>ResultSet</code>.</li>
- <li><code>Count Records</code> - Variables of <code>ResultSet</code> types will be iterated through showing the count of records as result. Variables will be stored as Strings.</li>
+ <li><code>Store As String</code> (default) - All variables on Variable Names list are stored as strings, will not iterate through a <code>ResultSet</code> when present on the list. <code>CLOB</code>s will be converted to Strings. <code>BLOB</code>s will be converted to Strings as if they were an UTF-8 encoded byte-array. Both <code>CLOB</code>s and <code>BLOB</code>s will be cut off after <code>jdbcsampler.max_retain_result_size</code> bytes.</li>
+ <li><code>Store As Object</code> - Variables of <code>ResultSet</code> type on Variables Names list will be stored as Object and can be accessed in subsequent tests/scripts and iterated, will not iterate through the <code>ResultSet</code>. <code>CLOB</code>s will be handled as if <code>Store As String</code> was selected. <code>BLOBs</code> will be stored as a byte array. Both <code>CLOB</code>s and <code>BLOB</code>s will be cut off after <code>jdbcsampler.max_retain_result_size</code> bytes.</li>
+ <li><code>Count Records</code> - Variables of <code>ResultSet</code> types will be iterated through showing the count of records as result. Variables will be stored as Strings. For <code>BLOB</code>s the size of the object will be stored.</li>
</ul>
</property>
</properties>
Modified: jmeter/trunk/xdocs/usermanual/properties_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/properties_reference.xml?rev=1761614&r1=1761613&r2=1761614&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/properties_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/properties_reference.xml Tue Sep 20 18:55:08 2016
@@ -488,6 +488,7 @@ Other parsers:<br/>
<section name="§-num;.26 JDBC Request configuration" anchor="jdbc_request">
<properties>
<property name="jdbcsampler.nullmarker"> String used to indicate a null value<br/>, defaults to:]NULL[</property>
+<property name="jdbcsampler.max_retain_result_size">Max bytes to store from a CLOB or BLOB in the sampler<br/>, defaults to: 65536 (bytes)</property>
</properties>
</section>
<section name="§-num;.27 OS Process Sampler configuration" anchor="os_sampler">