diff --git a/docs/images/screenshots/tcpsampler.png b/docs/images/screenshots/tcpsampler.png index b3452d624f..8dbdcc37c2 100644 Binary files a/docs/images/screenshots/tcpsampler.png and b/docs/images/screenshots/tcpsampler.png differ diff --git a/docs/images/screenshots/tcpsamplerconfig.png b/docs/images/screenshots/tcpsamplerconfig.png index d8304708c6..1a2d42eef0 100644 Binary files a/docs/images/screenshots/tcpsamplerconfig.png and b/docs/images/screenshots/tcpsamplerconfig.png differ diff --git a/src/core/org/apache/jmeter/resources/messages.properties b/src/core/org/apache/jmeter/resources/messages.properties index dbab111164..f61beb26f8 100644 --- a/src/core/org/apache/jmeter/resources/messages.properties +++ b/src/core/org/apache/jmeter/resources/messages.properties @@ -778,6 +778,7 @@ table_visualizer_status=Status table_visualizer_success=Success table_visualizer_thread_name=Thread Name table_visualizer_warning=Warning +tcp_classname=TCPClient classname\: tcp_config_title=TCP Sampler Config tcp_nodelay=Set NoDelay tcp_port=Port Number\: diff --git a/src/protocol/tcp/org/apache/jmeter/protocol/tcp/config/gui/TCPConfigGui.java b/src/protocol/tcp/org/apache/jmeter/protocol/tcp/config/gui/TCPConfigGui.java index 66355bf317..074559e48b 100644 --- a/src/protocol/tcp/org/apache/jmeter/protocol/tcp/config/gui/TCPConfigGui.java +++ b/src/protocol/tcp/org/apache/jmeter/protocol/tcp/config/gui/TCPConfigGui.java @@ -32,21 +32,11 @@ import org.apache.jmeter.gui.util.VerticalPanel; import org.apache.jmeter.protocol.tcp.sampler.TCPSampler; import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.util.JMeterUtils; +import org.apache.jorphan.gui.JLabeledTextField; public class TCPConfigGui extends AbstractConfigGui { - private final static String SERVER = "server"; //$NON-NLS-1$ - private final static String RE_USE_CONNECTION = "reUseConnection"; //$NON-NLS-1$ - - private final static String PORT = "port"; //$NON-NLS-1$ - - // NOTUSED yet private final static String FILENAME = "filename"; - // //$NON-NLS-1$ - private final static String TIMEOUT = "timeout"; //$NON-NLS-1$ - - private final static String NODELAY = "nodelay"; //$NON-NLS-1$ - - private final static String REQUEST = "request"; //$NON-NLS-1$ + private JLabeledTextField classname; private JTextField server; @@ -78,6 +68,8 @@ public class TCPConfigGui extends AbstractConfigGui { public void configure(TestElement element) { super.configure(element); + // N.B. this will be a config element, so we cannot use the getXXX() methods + classname.setText(element.getPropertyAsString(TCPSampler.CLASSNAME)); server.setText(element.getPropertyAsString(TCPSampler.SERVER)); // Default to original behaviour, i.e. re-use connection reUseConnection.setSelected(element.getPropertyAsBoolean(TCPSampler.RE_USE_CONNECTION,true)); @@ -101,6 +93,8 @@ public class TCPConfigGui extends AbstractConfigGui { */ public void modifyTestElement(TestElement element) { configureTestElement(element); + // N.B. this will be a config element, so we cannot use the setXXX() methods + element.setProperty(TCPSampler.CLASSNAME, classname.getText(), ""); element.setProperty(TCPSampler.SERVER, server.getText()); element.setProperty(TCPSampler.RE_USE_CONNECTION, reUseConnection.isSelected()); element.setProperty(TCPSampler.PORT, port.getText()); @@ -116,6 +110,7 @@ public class TCPConfigGui extends AbstractConfigGui { public void clearGui() { super.clearGui(); + classname.setText(""); //$NON-NLS-1$ server.setText(""); //$NON-NLS-1$ port.setText(""); //$NON-NLS-1$ timeout.setText(""); //$NON-NLS-1$ @@ -128,7 +123,6 @@ public class TCPConfigGui extends AbstractConfigGui { JLabel label = new JLabel(JMeterUtils.getResString("tcp_timeout")); // $NON-NLS-1$ timeout = new JTextField(10); - timeout.setName(TIMEOUT); label.setLabelFor(timeout); JPanel timeoutPanel = new JPanel(new BorderLayout(5, 0)); @@ -141,7 +135,6 @@ public class TCPConfigGui extends AbstractConfigGui { JLabel label = new JLabel(JMeterUtils.getResString("tcp_nodelay")); // $NON-NLS-1$ setNoDelay = new JCheckBox(); - setNoDelay.setName(NODELAY); label.setLabelFor(setNoDelay); JPanel nodelayPanel = new JPanel(new BorderLayout(5, 0)); @@ -154,7 +147,6 @@ public class TCPConfigGui extends AbstractConfigGui { JLabel label = new JLabel(JMeterUtils.getResString("server")); // $NON-NLS-1$ server = new JTextField(10); - server.setName(SERVER); label.setLabelFor(server); JPanel serverPanel = new JPanel(new BorderLayout(5, 0)); @@ -167,7 +159,6 @@ public class TCPConfigGui extends AbstractConfigGui { JLabel label = new JLabel(JMeterUtils.getResString("reuseconnection")); //$NON-NLS-1$ reUseConnection = new JCheckBox("", true); - reUseConnection.setName(RE_USE_CONNECTION); label.setLabelFor(reUseConnection); JPanel closePortPanel = new JPanel(new BorderLayout(5, 0)); @@ -180,7 +171,6 @@ public class TCPConfigGui extends AbstractConfigGui { JLabel label = new JLabel(JMeterUtils.getResString("tcp_port")); //$NON-NLS-1$ port = new JTextField(10); - port.setName(PORT); label.setLabelFor(port); JPanel PortPanel = new JPanel(new BorderLayout(5, 0)); @@ -193,7 +183,6 @@ public class TCPConfigGui extends AbstractConfigGui { JLabel reqLabel = new JLabel(JMeterUtils.getResString("tcp_request_data")); // $NON-NLS-1$ requestData = new JTextArea(3, 0); requestData.setLineWrap(true); - requestData.setName(REQUEST); reqLabel.setLabelFor(requestData); JPanel reqDataPanel = new JPanel(new BorderLayout(5, 0)); @@ -227,9 +216,12 @@ public class TCPConfigGui extends AbstractConfigGui { } VerticalPanel mainPanel = new VerticalPanel(); - mainPanel.add(createServerPanel()); + classname = new JLabeledTextField(JMeterUtils.getResString("tcp_classname")); + mainPanel.add(classname); + final JPanel serverPanel = createServerPanel(); + serverPanel.add(createPortPanel(), BorderLayout.EAST); + mainPanel.add(serverPanel); mainPanel.add(createClosePortPanel()); - mainPanel.add(createPortPanel()); mainPanel.add(createTimeoutPanel()); mainPanel.add(createNoDelayPanel()); mainPanel.add(createRequestPanel()); diff --git a/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPSampler.java b/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPSampler.java index c04b62c7a8..0460ec0489 100644 --- a/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPSampler.java +++ b/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPSampler.java @@ -49,6 +49,7 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { private static final Logger log = LoggingManager.getLoggerForClass(); + //++ JMX file constants - do not change public static final String SERVER = "TCPSampler.server"; //$NON-NLS-1$ public static final String PORT = "TCPSampler.port"; //$NON-NLS-1$ @@ -64,6 +65,7 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { public static final String REQUEST = "TCPSampler.request"; //$NON-NLS-1$ public static final String RE_USE_CONNECTION = "TCPSampler.reUseConnection"; //$NON-NLS-1$ + //-- JMX file constants - do not change private static final String TCPKEY = "TCP"; //$NON-NLS-1$ key for HashMap @@ -75,11 +77,11 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { // JMeterUtils.getPropDefault("tcp.status.regex",""); // Otherwise, the response is scanned for these strings - private static final String STATUS_PREFIX = JMeterUtils.getPropDefault("tcp.status.prefix", ""); + private static final String STATUS_PREFIX = JMeterUtils.getPropDefault("tcp.status.prefix", ""); //$NON-NLS-1$ - private static final String STATUS_SUFFIX = JMeterUtils.getPropDefault("tcp.status.suffix", ""); + private static final String STATUS_SUFFIX = JMeterUtils.getPropDefault("tcp.status.suffix", ""); //$NON-NLS-1$ - private static final String STATUS_PROPERTIES = JMeterUtils.getPropDefault("tcp.status.properties", ""); + private static final String STATUS_PROPERTIES = JMeterUtils.getPropDefault("tcp.status.properties", ""); //$NON-NLS-1$ private static final Properties statusProps = new Properties(); @@ -87,22 +89,21 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { static { boolean hsp = false; - log.debug("Protocol Handler name=" + getClassname()); - log.debug("Status prefix=" + STATUS_PREFIX); - log.debug("Status suffix=" + STATUS_SUFFIX); - log.debug("Status properties=" + STATUS_PROPERTIES); + log.debug("Status prefix=" + STATUS_PREFIX); //$NON-NLS-1$ + log.debug("Status suffix=" + STATUS_SUFFIX); //$NON-NLS-1$ + log.debug("Status properties=" + STATUS_PROPERTIES); //$NON-NLS-1$ if (STATUS_PROPERTIES.length() > 0) { File f = new File(STATUS_PROPERTIES); FileInputStream fis = null; try { fis = new FileInputStream(f); statusProps.load(fis); - log.debug("Successfully loaded properties"); + log.debug("Successfully loaded properties"); //$NON-NLS-1$ hsp = true; } catch (FileNotFoundException e) { - log.debug("Property file not found"); + log.debug("Property file not found"); //$NON-NLS-1$ } catch (IOException e) { - log.debug("Property file error " + e.toString()); + log.debug("Property file error " + e.toString()); //$NON-NLS-1$ } finally { JOrphanUtils.closeQuietly(fis); } @@ -120,9 +121,7 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { private transient TCPClient protocolHandler; public TCPSampler() { - log.debug("Created " + this); - protocolHandler = getProtocol(); - log.debug("Using Protocol Handler: " + protocolHandler.getClass().getName()); + log.debug("Created " + this); //$NON-NLS-1$ } private String getError() { @@ -177,8 +176,8 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { return getPropertyAsString(SERVER); } - public void setReUseConnection(String newServer) { - this.setProperty(RE_USE_CONNECTION, newServer); + public void setReUseConnection(String reuse) { + this.setProperty(RE_USE_CONNECTION, reuse); } public boolean isReUseConnection() { @@ -225,6 +224,18 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { return getPropertyAsBoolean(NODELAY); } + public void setClassname(String classname) { + this.setProperty(CLASSNAME, classname, ""); //$NON-NLS-1$ + } + + public String getClassname() { + String clazz = getPropertyAsString(CLASSNAME,""); + if (clazz==null || clazz.length()==0){ + clazz = JMeterUtils.getPropDefault("tcp.handler", "TCPClientImpl"); //$NON-NLS-1$ $NON-NLS-2$ + } + return clazz; + } + /** * Returns a formatted string label describing this sampler Example output: * Tcp://Tcp.nowhere.com/pub/README.txt @@ -232,15 +243,10 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { * @return a formatted string label describing this sampler */ public String getLabel() { - return ("tcp://" + this.getServer() + ":" + this.getPort());//$NON-NLS-1$ + return ("tcp://" + this.getServer() + ":" + this.getPort());//$NON-NLS-1$ $NON-NLS-2$ } - private static String getClassname() { - String className = JMeterUtils.getPropDefault("tcp.handler", "TCPClientImpl"); - return className; - } - - private static final String protoPrefix = "org.apache.jmeter.protocol.tcp.sampler."; + private static final String protoPrefix = "org.apache.jmeter.protocol.tcp.sampler."; //$NON-NLS-1$ private Class getClass(String className) { Class c = null; @@ -250,7 +256,7 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { try { c = Class.forName(protoPrefix + className, false, Thread.currentThread().getContextClassLoader()); } catch (ClassNotFoundException e1) { - log.error("Could not find protocol class " + className); + log.error("Could not find protocol class '" + className+"'"); //$NON-NLS-1$ } } return c; @@ -260,13 +266,16 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { private TCPClient getProtocol() { TCPClient TCPClient = null; Class javaClass = getClass(getClassname()); + if (javaClass == null){ + return null; + } try { TCPClient = (TCPClient) javaClass.newInstance(); if (log.isDebugEnabled()) { - log.debug(this + "Created: " + getClassname() + "@" + Integer.toHexString(TCPClient.hashCode())); + log.debug(this + "Created: " + getClassname() + "@" + Integer.toHexString(TCPClient.hashCode())); //$NON-NLS-1$ } } catch (Exception e) { - log.error(this + " Exception creating: " + getClassname(), e); + log.error(this + " Exception creating: " + getClassname(), e); //$NON-NLS-1$ } return TCPClient; } @@ -276,15 +285,17 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { log.debug(getLabel() + " " + getFilename() + " " + getUsername() + " " + getPassword()); SampleResult res = new SampleResult(); boolean isSuccessful = false; - res.setSampleLabel(getName());// Use the test element name for the - // label - res.setSamplerData("Host: " + getServer() + " Port: " + getPort()); + res.setSampleLabel(getName());// Use the test element name for the label + res.setSamplerData("Host: " + getServer() + " Port: " + getPort()); //$NON-NLS-1$ $NON-NLS-2$ res.sampleStart(); try { Socket sock = getSocket(); if (sock == null) { - res.setResponseCode("500"); + res.setResponseCode("500"); //$NON-NLS-1$ res.setResponseMessage(getError()); + } else if (protocolHandler == null){ + res.setResponseCode("500"); //$NON-NLS-1$ + res.setResponseMessage("Protocol handler not found"); } else { InputStream is = sock.getInputStream(); OutputStream os = sock.getOutputStream(); @@ -296,7 +307,7 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { res.setResponseData(in.getBytes()); res.setDataType(SampleResult.TEXT); res.setResponseCodeOK(); - res.setResponseMessage("OK"); + res.setResponseMessage("OK"); //$NON-NLS-1$ isSuccessful = true; // Reset the status code if the message contains one if (STATUS_PREFIX.length() > 0) { @@ -307,12 +318,12 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { res.setResponseCode(rc); isSuccessful = checkResponseCode(rc); if (haveStatusProps) { - res.setResponseMessage(statusProps.getProperty(rc, "Status code not found in properties")); + res.setResponseMessage(statusProps.getProperty(rc, "Status code not found in properties")); //$NON-NLS-1$ } else { res.setResponseMessage("No status property file"); } } else { - res.setResponseCode("999"); + res.setResponseCode("999"); //$NON-NLS-1$ res.setResponseMessage("Status value not found"); isSuccessful = false; } @@ -320,7 +331,7 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { } } catch (IOException ex) { log.debug("", ex); - res.setResponseCode("500"); + res.setResponseCode("500"); //$NON-NLS-1$ res.setResponseMessage(ex.toString()); closeSocket(); } finally { @@ -343,18 +354,21 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { * @return whether this represents success or not */ private boolean checkResponseCode(String rc) { - if (rc.compareTo("400") >= 0 && rc.compareTo("499") <= 0) { + if (rc.compareTo("400") >= 0 && rc.compareTo("499") <= 0) { //$NON-NLS-1$ $NON-NLS-2$ return false; } - if (rc.compareTo("500") >= 0 && rc.compareTo("599") <= 0) { + if (rc.compareTo("500") >= 0 && rc.compareTo("599") <= 0) { //$NON-NLS-1$ $NON-NLS-2$ return false; } return true; } public void threadStarted() { - log.debug("Thread Started"); - } + log.debug("Thread Started"); //$NON-NLS-1$ + protocolHandler = getProtocol(); + log.debug("Using Protocol Handler: " + //$NON-NLS-1$ + (protocolHandler == null ? "NONE" : protocolHandler.getClass().getName())); //$NON-NLS-1$ +} private void closeSocket() { Map cp = (Map) tp.get(); @@ -364,13 +378,13 @@ public class TCPSampler extends AbstractSampler implements ThreadListener { try { con.close(); } catch (IOException e) { - log.warn("Error closing socket "+e); + log.warn("Error closing socket "+e); //$NON-NLS-1$ } } } public void threadFinished() { - log.debug("Thread Finished"); + log.debug("Thread Finished"); //$NON-NLS-1$ closeSocket(); } } diff --git a/xdocs/changes.xml b/xdocs/changes.xml index 27fdd86aa1..e7b349038d 100644 --- a/xdocs/changes.xml +++ b/xdocs/changes.xml @@ -153,6 +153,7 @@ These are implemented in the AbstractTestElement class which all elements should
The TCP Sampler opens a TCP/IP connection to the specified server. @@ -1018,9 +1017,10 @@ Currently the only way to changes these is via the SampleResult methods:
The TCP Sampler Config provides default data for the TCP Sampler @@ -2723,8 +2722,10 @@ The Database URL and JDBC Driver class are defined by the provider of the JDBC i