├── .gitignore ├── README.md ├── src └── main │ └── java │ └── JMeter │ └── plugins │ ├── functional │ └── samplers │ │ └── websocket │ │ ├── WebSocketImplementation.java │ │ ├── WebSocketSamplerGui.java │ │ ├── ServiceSocket.java │ │ ├── WebSocketSampler.java │ │ ├── WebSocketSamplerPanel.form │ │ └── WebSocketSamplerPanel.java │ └── controler │ └── websocketapp │ ├── WebSocketSamplerGui.java │ ├── WebSocketApplicationResponse.form │ ├── WebSocketApplicationRequest.form │ ├── WebSocketApplicationResponse.java │ ├── WebSocketApplicationRequest.java │ ├── WebSocketSampler.java │ ├── WebSocketApplicationConfig.form │ └── WebSocketApplicationConfig.java ├── pom.xml └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JMeter 2 | ====== 3 | 4 | JMeter - WebSocket Sampler 5 | 6 | Compiled binary can be downloaded from the Releases. 7 | 8 | Please have a look at the [Wiki pages](https://github.com/maciejzaleski/JMeter-WebSocketSampler/wiki) for instructions on how to install the plug-in. 9 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/functional/samplers/websocket/WebSocketImplementation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.samplers.websocket; 6 | 7 | /** 8 | * 9 | * @author Maciej Zaleski 10 | */ 11 | public enum WebSocketImplementation { 12 | RFC6455 13 | } 14 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | co.uk.bugtrap 6 | JMeterWebSocketSampler 7 | 1.0.2-SNAPSHOT 8 | jar 9 | 10 | JMeterWebSocketSampler 11 | http://maven.apache.org 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 2.3.2 18 | 19 | 1.7 20 | 1.7 21 | 22 | **\JMeter\plugins\controler\websocketapp\** 23 | 24 | 25 | 26 | 27 | maven-jar-plugin 28 | 2.3.1 29 | 30 | 31 | default-jar 32 | package 33 | 34 | jar 35 | 36 | 37 | 38 | **/JMeter/plugins/functional/controler/**/* 39 | **/JMeter/plugins/controler/websocketapp/** 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | UTF-8 49 | 50 | 51 | 52 | 53 | junit 54 | junit 55 | 3.8.1 56 | test 57 | 58 | 59 | org.eclipse.jetty.websocket 60 | websocket-client 61 | 9.1.1.v20140108 62 | hybrid 63 | 64 | 65 | org.apache.jmeter 66 | ApacheJMeter 67 | 2.10 68 | 69 | 70 | org.apache.jmeter 71 | ApacheJMeter_core 72 | 2.10 73 | 74 | 75 | org.apache.jmeter 76 | ApacheJMeter_http 77 | 2.10 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketSamplerGui.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.controler.websocketapp; 6 | 7 | import java.awt.BorderLayout; 8 | import org.apache.jmeter.config.Arguments; 9 | import org.apache.jmeter.config.gui.ArgumentsPanel; 10 | import org.apache.jmeter.control.gui.AbstractControllerGui; 11 | import org.apache.jmeter.testelement.TestElement; 12 | import org.apache.jorphan.logging.LoggingManager; 13 | import org.apache.log.Logger; 14 | 15 | /** 16 | * 17 | * @author Maciej Zaleski 18 | */ 19 | public class WebSocketSamplerGui extends AbstractControllerGui { 20 | 21 | private WebSocketApplicationConfig webSocketSamplerPanel; 22 | private static final Logger log = LoggingManager.getLoggerForClass(); 23 | 24 | public WebSocketSamplerGui() { 25 | super(); 26 | init(); 27 | initFields(); 28 | 29 | setLayout(new BorderLayout(0, 5)); 30 | setBorder(makeBorder()); 31 | 32 | add(makeTitlePanel(), BorderLayout.NORTH); 33 | add(webSocketSamplerPanel, BorderLayout.CENTER); 34 | } 35 | 36 | @Override 37 | public String getStaticLabel() { 38 | return "WebSocket Sampler"; 39 | } 40 | 41 | @Override 42 | public String getLabelResource() { 43 | throw new IllegalStateException("This shouldn't be called"); //$NON-NLS-1$ 44 | } 45 | 46 | @Override 47 | public void configure(TestElement element) { 48 | super.configure(element); 49 | if (element instanceof WebSocketSampler) { 50 | WebSocketSampler webSocketSamplerTestElement = (WebSocketSampler) element; 51 | webSocketSamplerPanel.setServerAddress(webSocketSamplerTestElement.getServerAddress()); 52 | webSocketSamplerPanel.setServerPort(webSocketSamplerTestElement.getServerPort()); 53 | webSocketSamplerPanel.setImplementation(webSocketSamplerTestElement.getImplementation()); 54 | webSocketSamplerPanel.setProtocol(webSocketSamplerTestElement.getProtocol()); 55 | webSocketSamplerPanel.setContextPath(webSocketSamplerTestElement.getContextPath()); 56 | webSocketSamplerPanel.setContentEncoding(webSocketSamplerTestElement.getContentEncoding()); 57 | webSocketSamplerPanel.setRequestPayload(webSocketSamplerTestElement.getRequestPayload()); 58 | webSocketSamplerPanel.setResponseTimeout(webSocketSamplerTestElement.getResponseTimeout()); 59 | webSocketSamplerPanel.setConnectionTimeout(webSocketSamplerTestElement.getConnectionTimeout()); 60 | webSocketSamplerPanel.setIgnoreSslErrors(webSocketSamplerTestElement.isIgnoreSslErrors()); 61 | webSocketSamplerPanel.setStreamingConnection(webSocketSamplerTestElement.isStreamingConnection()); 62 | webSocketSamplerPanel.setConnectionId(webSocketSamplerTestElement.getConnectionId()); 63 | webSocketSamplerPanel.setResponsePattern(webSocketSamplerTestElement.getResponsePattern()); 64 | webSocketSamplerPanel.setCloseConncectionPattern(webSocketSamplerTestElement.getCloseConncectionPattern()); 65 | webSocketSamplerPanel.setProxyAddress(webSocketSamplerTestElement.getProxyAddress()); 66 | webSocketSamplerPanel.setProxyPassword(webSocketSamplerTestElement.getProxyPassword()); 67 | webSocketSamplerPanel.setProxyPort(webSocketSamplerTestElement.getProxyPort()); 68 | webSocketSamplerPanel.setProxyUsername(webSocketSamplerTestElement.getProxyUsername()); 69 | webSocketSamplerPanel.setMessageBacklog(webSocketSamplerTestElement.getMessageBacklog()); 70 | 71 | Arguments queryStringParameters = webSocketSamplerTestElement.getQueryStringParameters(); 72 | if (queryStringParameters != null) { 73 | webSocketSamplerPanel.getAttributePanel().configure(queryStringParameters); 74 | } 75 | } 76 | } 77 | 78 | @Override 79 | public TestElement createTestElement() { 80 | WebSocketSampler preproc = new WebSocketSampler(); 81 | configureTestElement(preproc); 82 | return preproc; 83 | } 84 | 85 | @Override 86 | public void modifyTestElement(TestElement te) { 87 | configureTestElement(te); 88 | if (te instanceof WebSocketSampler) { 89 | WebSocketSampler webSocketSamplerTestElement = (WebSocketSampler) te; 90 | webSocketSamplerTestElement.setServerAddress(webSocketSamplerPanel.getServerAddress()); 91 | webSocketSamplerTestElement.setServerPort(webSocketSamplerPanel.getServerPort()); 92 | webSocketSamplerTestElement.setImplementation(webSocketSamplerPanel.getImplementation()); 93 | webSocketSamplerTestElement.setProtocol(webSocketSamplerPanel.getProtocol()); 94 | webSocketSamplerTestElement.setContextPath(webSocketSamplerPanel.getContextPath()); 95 | webSocketSamplerTestElement.setContentEncoding(webSocketSamplerPanel.getContentEncoding()); 96 | webSocketSamplerTestElement.setRequestPayload(webSocketSamplerPanel.getRequestPayload()); 97 | webSocketSamplerTestElement.setConnectionTimeout(webSocketSamplerPanel.getConnectionTimeout()); 98 | webSocketSamplerTestElement.setResponseTimeout(webSocketSamplerPanel.getResponseTimeout()); 99 | webSocketSamplerTestElement.setIgnoreSslErrors(webSocketSamplerPanel.isIgnoreSslErrors()); 100 | webSocketSamplerTestElement.setStreamingConnection(webSocketSamplerPanel.isStreamingConnection()); 101 | webSocketSamplerTestElement.setConnectionId(webSocketSamplerPanel.getConnectionId()); 102 | webSocketSamplerTestElement.setResponsePattern(webSocketSamplerPanel.getResponsePattern()); 103 | webSocketSamplerTestElement.setCloseConncectionPattern(webSocketSamplerPanel.getCloseConncectionPattern()); 104 | webSocketSamplerTestElement.setProxyAddress(webSocketSamplerPanel.getProxyAddress()); 105 | webSocketSamplerTestElement.setProxyPassword(webSocketSamplerPanel.getProxyPassword()); 106 | webSocketSamplerTestElement.setProxyPort(webSocketSamplerPanel.getProxyPort()); 107 | webSocketSamplerTestElement.setProxyUsername(webSocketSamplerPanel.getProxyUsername()); 108 | webSocketSamplerTestElement.setMessageBacklog(webSocketSamplerPanel.getMessageBacklog()); 109 | 110 | ArgumentsPanel queryStringParameters = webSocketSamplerPanel.getAttributePanel(); 111 | if (queryStringParameters != null) { 112 | webSocketSamplerTestElement.setQueryStringParameters((Arguments)queryStringParameters.createTestElement()); 113 | } 114 | } 115 | } 116 | 117 | @Override 118 | public void clearGui() { 119 | super.clearGui(); 120 | initFields(); 121 | } 122 | 123 | private void init() { 124 | webSocketSamplerPanel = new WebSocketApplicationConfig(); 125 | } 126 | 127 | private void initFields() { 128 | webSocketSamplerPanel.initFields(); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketApplicationResponse.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 |
151 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/functional/samplers/websocket/WebSocketSamplerGui.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.samplers.websocket; 6 | 7 | import java.awt.BorderLayout; 8 | import org.apache.jmeter.config.Arguments; 9 | import org.apache.jmeter.config.gui.ArgumentsPanel; 10 | import org.apache.jmeter.samplers.gui.AbstractSamplerGui; 11 | import org.apache.jmeter.testelement.TestElement; 12 | import org.apache.jorphan.logging.LoggingManager; 13 | import org.apache.log.Logger; 14 | 15 | /** 16 | * 17 | * @author Maciej Zaleski 18 | */ 19 | public class WebSocketSamplerGui extends AbstractSamplerGui { 20 | 21 | private WebSocketSamplerPanel webSocketSamplerPanel; 22 | private static final Logger log = LoggingManager.getLoggerForClass(); 23 | 24 | public WebSocketSamplerGui() { 25 | super(); 26 | init(); 27 | initFields(); 28 | 29 | setLayout(new BorderLayout(0, 5)); 30 | setBorder(makeBorder()); 31 | 32 | add(makeTitlePanel(), BorderLayout.NORTH); 33 | add(webSocketSamplerPanel, BorderLayout.CENTER); 34 | } 35 | 36 | @Override 37 | public String getStaticLabel() { 38 | return "WebSocket Sampler"; 39 | } 40 | 41 | @Override 42 | public String getLabelResource() { 43 | throw new IllegalStateException("This shouldn't be called"); //$NON-NLS-1$ 44 | } 45 | 46 | @Override 47 | public void configure(TestElement element) { 48 | super.configure(element); 49 | if (element instanceof WebSocketSampler) { 50 | WebSocketSampler webSocketSamplerTestElement = (WebSocketSampler) element; 51 | webSocketSamplerPanel.setServerAddress(webSocketSamplerTestElement.getServerAddress()); 52 | webSocketSamplerPanel.setServerPort(webSocketSamplerTestElement.getServerPort()); 53 | webSocketSamplerPanel.setImplementation(webSocketSamplerTestElement.getImplementation()); 54 | webSocketSamplerPanel.setProtocol(webSocketSamplerTestElement.getProtocol()); 55 | webSocketSamplerPanel.setContextPath(webSocketSamplerTestElement.getContextPath()); 56 | webSocketSamplerPanel.setContentEncoding(webSocketSamplerTestElement.getContentEncoding()); 57 | webSocketSamplerPanel.setRequestPayload(webSocketSamplerTestElement.getRequestPayload()); 58 | webSocketSamplerPanel.setResponseTimeout(webSocketSamplerTestElement.getResponseTimeout()); 59 | webSocketSamplerPanel.setConnectionTimeout(webSocketSamplerTestElement.getConnectionTimeout()); 60 | webSocketSamplerPanel.setIgnoreSslErrors(webSocketSamplerTestElement.isIgnoreSslErrors()); 61 | webSocketSamplerPanel.setStreamingConnection(webSocketSamplerTestElement.isStreamingConnection()); 62 | webSocketSamplerPanel.setConnectionId(webSocketSamplerTestElement.getConnectionId()); 63 | webSocketSamplerPanel.setResponsePattern(webSocketSamplerTestElement.getResponsePattern()); 64 | webSocketSamplerPanel.setCloseConncectionPattern(webSocketSamplerTestElement.getCloseConncectionPattern()); 65 | webSocketSamplerPanel.setProxyAddress(webSocketSamplerTestElement.getProxyAddress()); 66 | webSocketSamplerPanel.setProxyPassword(webSocketSamplerTestElement.getProxyPassword()); 67 | webSocketSamplerPanel.setProxyPort(webSocketSamplerTestElement.getProxyPort()); 68 | webSocketSamplerPanel.setProxyUsername(webSocketSamplerTestElement.getProxyUsername()); 69 | webSocketSamplerPanel.setMessageBacklog(webSocketSamplerTestElement.getMessageBacklog()); 70 | webSocketSamplerPanel.setOverrideResponsePattern(webSocketSamplerTestElement.isOverrideResponsePattern()); 71 | webSocketSamplerPanel.setOverrideDisconnectPattern(webSocketSamplerTestElement.isOverrideDisconnectPattern()); 72 | 73 | Arguments queryStringParameters = webSocketSamplerTestElement.getQueryStringParameters(); 74 | if (queryStringParameters != null) { 75 | webSocketSamplerPanel.getAttributePanel().configure(queryStringParameters); 76 | } 77 | } 78 | } 79 | 80 | @Override 81 | public TestElement createTestElement() { 82 | WebSocketSampler preproc = new WebSocketSampler(); 83 | configureTestElement(preproc); 84 | return preproc; 85 | } 86 | 87 | @Override 88 | public void modifyTestElement(TestElement te) { 89 | configureTestElement(te); 90 | if (te instanceof WebSocketSampler) { 91 | WebSocketSampler webSocketSamplerTestElement = (WebSocketSampler) te; 92 | webSocketSamplerTestElement.setServerAddress(webSocketSamplerPanel.getServerAddress()); 93 | webSocketSamplerTestElement.setServerPort(webSocketSamplerPanel.getServerPort()); 94 | webSocketSamplerTestElement.setImplementation(webSocketSamplerPanel.getImplementation()); 95 | webSocketSamplerTestElement.setProtocol(webSocketSamplerPanel.getProtocol()); 96 | webSocketSamplerTestElement.setContextPath(webSocketSamplerPanel.getContextPath()); 97 | webSocketSamplerTestElement.setContentEncoding(webSocketSamplerPanel.getContentEncoding()); 98 | webSocketSamplerTestElement.setRequestPayload(webSocketSamplerPanel.getRequestPayload()); 99 | webSocketSamplerTestElement.setConnectionTimeout(webSocketSamplerPanel.getConnectionTimeout()); 100 | webSocketSamplerTestElement.setResponseTimeout(webSocketSamplerPanel.getResponseTimeout()); 101 | webSocketSamplerTestElement.setIgnoreSslErrors(webSocketSamplerPanel.isIgnoreSslErrors()); 102 | webSocketSamplerTestElement.setStreamingConnection(webSocketSamplerPanel.isStreamingConnection()); 103 | webSocketSamplerTestElement.setConnectionId(webSocketSamplerPanel.getConnectionId()); 104 | webSocketSamplerTestElement.setResponsePattern(webSocketSamplerPanel.getResponsePattern()); 105 | webSocketSamplerTestElement.setCloseConncectionPattern(webSocketSamplerPanel.getCloseConncectionPattern()); 106 | webSocketSamplerTestElement.setProxyAddress(webSocketSamplerPanel.getProxyAddress()); 107 | webSocketSamplerTestElement.setProxyPassword(webSocketSamplerPanel.getProxyPassword()); 108 | webSocketSamplerTestElement.setProxyPort(webSocketSamplerPanel.getProxyPort()); 109 | webSocketSamplerTestElement.setProxyUsername(webSocketSamplerPanel.getProxyUsername()); 110 | webSocketSamplerTestElement.setMessageBacklog(webSocketSamplerPanel.getMessageBacklog()); 111 | webSocketSamplerTestElement.setOverrideResponsePattern(webSocketSamplerPanel.isOverrideResponsePattern()); 112 | webSocketSamplerTestElement.setOverrideDisconnectPattern(webSocketSamplerPanel.isOverrideDisconnectPattern()); 113 | 114 | 115 | ArgumentsPanel queryStringParameters = webSocketSamplerPanel.getAttributePanel(); 116 | if (queryStringParameters != null) { 117 | webSocketSamplerTestElement.setQueryStringParameters((Arguments)queryStringParameters.createTestElement()); 118 | } 119 | } 120 | } 121 | 122 | @Override 123 | public void clearGui() { 124 | super.clearGui(); 125 | initFields(); 126 | } 127 | 128 | private void init() { 129 | webSocketSamplerPanel = new WebSocketSamplerPanel(); 130 | } 131 | 132 | private void initFields() { 133 | webSocketSamplerPanel.initFields(); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketApplicationRequest.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 |
166 |
167 | 168 | 169 | 170 | 171 | <Editor/> 172 | <Renderer/> 173 | </Column> 174 | <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> 175 | <Title/> 176 | <Editor/> 177 | <Renderer/> 178 | </Column> 179 | <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> 180 | <Title/> 181 | <Editor/> 182 | <Renderer/> 183 | </Column> 184 | <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> 185 | <Title/> 186 | <Editor/> 187 | <Renderer/> 188 | </Column> 189 | </TableColumnModel> 190 | </Property> 191 | <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> 192 | <TableHeader reorderingAllowed="true" resizingAllowed="true"/> 193 | </Property> 194 | </Properties> 195 | </Component> 196 | </SubComponents> 197 | </Container> 198 | </SubComponents> 199 | </Container> 200 | </SubComponents> 201 | </Form> 202 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketApplicationResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.controler.websocketapp; 6 | 7 | import JMeter.plugins.functional.samplers.websocket.*; 8 | import java.awt.Color; 9 | import org.apache.jmeter.config.gui.ArgumentsPanel; 10 | import org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel; 11 | import org.apache.jorphan.logging.LoggingManager; 12 | import org.apache.log.Logger; 13 | 14 | /** 15 | * 16 | * @author Maciej Zaleski 17 | */ 18 | public class WebSocketApplicationResponse extends javax.swing.JPanel { 19 | private static final Logger log = LoggingManager.getLoggerForClass(); 20 | private HTTPArgumentsPanel attributePanel; 21 | 22 | /** 23 | * Creates new form WebSocketSamplerPanel 24 | */ 25 | public WebSocketApplicationResponse() { 26 | initComponents(); 27 | 28 | attributePanel = new HTTPArgumentsPanel(); 29 | querystringAttributesPanel.add(attributePanel); 30 | } 31 | 32 | /** 33 | * This method is called from within the constructor to initialize the form. 34 | * WARNING: Do NOT modify this code. The content of this method is always 35 | * regenerated by the Form Editor. 36 | */ 37 | @SuppressWarnings("unchecked") 38 | // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents 39 | private void initComponents() { 40 | 41 | jPanel5 = new javax.swing.JPanel(); 42 | jLabel7 = new javax.swing.JLabel(); 43 | responsePatternTextField = new javax.swing.JTextField(); 44 | jPanel4 = new javax.swing.JPanel(); 45 | jScrollPane1 = new javax.swing.JScrollPane(); 46 | requestPayloadEditorPane = new javax.swing.JEditorPane(); 47 | jPanel1 = new javax.swing.JPanel(); 48 | 49 | jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Server message")); 50 | 51 | jLabel7.setText("Response pattern:"); 52 | 53 | javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); 54 | jPanel5.setLayout(jPanel5Layout); 55 | jPanel5Layout.setHorizontalGroup( 56 | jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 57 | .addGroup(jPanel5Layout.createSequentialGroup() 58 | .addContainerGap() 59 | .addComponent(jLabel7) 60 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 61 | .addComponent(responsePatternTextField) 62 | .addContainerGap()) 63 | ); 64 | jPanel5Layout.setVerticalGroup( 65 | jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 66 | .addGroup(jPanel5Layout.createSequentialGroup() 67 | .addContainerGap() 68 | .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 69 | .addComponent(jLabel7) 70 | .addComponent(responsePatternTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 71 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 72 | ); 73 | 74 | jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Client response")); 75 | 76 | jScrollPane1.setViewportView(requestPayloadEditorPane); 77 | 78 | javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 79 | jPanel1.setLayout(jPanel1Layout); 80 | jPanel1Layout.setHorizontalGroup( 81 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 82 | .addGap(0, 0, Short.MAX_VALUE) 83 | ); 84 | jPanel1Layout.setVerticalGroup( 85 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 86 | .addGap(0, 130, Short.MAX_VALUE) 87 | ); 88 | 89 | javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); 90 | jPanel4.setLayout(jPanel4Layout); 91 | jPanel4Layout.setHorizontalGroup( 92 | jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 93 | .addGroup(jPanel4Layout.createSequentialGroup() 94 | .addContainerGap() 95 | .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 96 | .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 493, Short.MAX_VALUE) 97 | .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 98 | .addContainerGap()) 99 | ); 100 | jPanel4Layout.setVerticalGroup( 101 | jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 102 | .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() 103 | .addContainerGap() 104 | .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 105 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 106 | .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) 107 | .addContainerGap()) 108 | ); 109 | 110 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 111 | this.setLayout(layout); 112 | layout.setHorizontalGroup( 113 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 114 | .addGroup(layout.createSequentialGroup() 115 | .addContainerGap() 116 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 117 | .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 118 | .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 119 | .addContainerGap()) 120 | ); 121 | layout.setVerticalGroup( 122 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 123 | .addGroup(layout.createSequentialGroup() 124 | .addContainerGap() 125 | .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 126 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 127 | .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 128 | .addContainerGap()) 129 | ); 130 | }// </editor-fold>//GEN-END:initComponents 131 | // Variables declaration - do not modify//GEN-BEGIN:variables 132 | private javax.swing.JLabel jLabel7; 133 | private javax.swing.JPanel jPanel1; 134 | private javax.swing.JPanel jPanel4; 135 | private javax.swing.JPanel jPanel5; 136 | private javax.swing.JScrollPane jScrollPane1; 137 | private javax.swing.JEditorPane requestPayloadEditorPane; 138 | private javax.swing.JTextField responsePatternTextField; 139 | // End of variables declaration//GEN-END:variables 140 | 141 | public void initFields() { 142 | } 143 | 144 | public void setCloseConncectionPattern(String closeConncectionPattern) { 145 | closeConncectionPatternTextField.setText(closeConncectionPattern); 146 | } 147 | 148 | public String getCloseConncectionPattern() { 149 | return closeConncectionPatternTextField.getText(); 150 | } 151 | 152 | public void setConnectionId(String connectionId) { 153 | connectionIdTextField.setText(connectionId); 154 | } 155 | 156 | public String getConnectionId() { 157 | return connectionIdTextField.getText(); 158 | } 159 | 160 | public void setContentEncoding(String contentEncoding) { 161 | contentEncodingTextField.setText(contentEncoding); 162 | } 163 | 164 | public String getContentEncoding() { 165 | return contentEncodingTextField.getText(); 166 | } 167 | 168 | public void setContextPath(String contextPath) { 169 | contextPathTextField.setText(contextPath); 170 | } 171 | 172 | public String getContextPath() { 173 | return contextPathTextField.getText(); 174 | } 175 | 176 | public void setProtocol(String protocol) { 177 | protocolTextField.setText(protocol); 178 | } 179 | 180 | public String getProtocol() { 181 | return protocolTextField.getText(); 182 | } 183 | 184 | public void setProxyAddress(String proxyAddress) { 185 | proxyAddressTextField.setText(proxyAddress); 186 | } 187 | 188 | public String getProxyAddress() { 189 | return proxyAddressTextField.getText(); 190 | } 191 | 192 | public void setProxyPassword(String proxyPassword) { 193 | proxyPasswordTextField.setText(proxyPassword); 194 | } 195 | 196 | public String getProxyPassword() { 197 | return proxyPasswordTextField.getText(); 198 | } 199 | 200 | public void setProxyPort(String proxyPort) { 201 | proxyPortTextField.setText(proxyPort); 202 | } 203 | 204 | public String getProxyPort() { 205 | return proxyPortTextField.getText(); 206 | } 207 | 208 | public void setProxyUsername(String proxyUsername) { 209 | proxyUsernameTextField.setText(proxyUsername); 210 | } 211 | 212 | public String getProxyUsername() { 213 | return proxyUsernameTextField.getText(); 214 | } 215 | 216 | public void setResponsePattern(String responsePattern) { 217 | responsePatternTextField.setText(responsePattern); 218 | } 219 | 220 | public String getResponsePattern() { 221 | return responsePatternTextField.getText(); 222 | } 223 | 224 | public void setResponseTimeout(String responseTimeout) { 225 | responseTimeoutTextField.setText(responseTimeout); 226 | } 227 | 228 | public String getResponseTimeout() { 229 | return responseTimeoutTextField.getText(); 230 | } 231 | 232 | public void setConnectionTimeout(String connectionTimeout) { 233 | connectionTimeoutTextField.setText(connectionTimeout); 234 | } 235 | 236 | public String getConnectionTimeout() { 237 | return connectionTimeoutTextField.getText(); 238 | } 239 | 240 | public void setServerAddress(String serverAddress) { 241 | serverAddressTextField.setText(serverAddress); 242 | } 243 | 244 | public String getServerAddress() { 245 | return serverAddressTextField.getText(); 246 | } 247 | 248 | public void setServerPort(String serverPort) { 249 | serverPortTextField.setText(serverPort); 250 | } 251 | 252 | public String getServerPort() { 253 | return serverPortTextField.getText(); 254 | } 255 | 256 | public void setRequestPayload(String requestPayload) { 257 | requestPayloadEditorPane.setText(requestPayload); 258 | } 259 | 260 | public String getRequestPayload() { 261 | return requestPayloadEditorPane.getText(); 262 | } 263 | 264 | public void setStreamingConnection(Boolean streamingConnection) { 265 | streamingConnectionCheckBox.setSelected(streamingConnection); 266 | } 267 | 268 | public Boolean isStreamingConnection() { 269 | return streamingConnectionCheckBox.isSelected(); 270 | } 271 | 272 | public void setIgnoreSslErrors(Boolean ignoreSslErrors) { 273 | ignoreSslErrorsCheckBox.setSelected(ignoreSslErrors); 274 | } 275 | 276 | public Boolean isIgnoreSslErrors() { 277 | return ignoreSslErrorsCheckBox.isSelected(); 278 | } 279 | 280 | public void setImplementation(String implementation) { 281 | implementationComboBox.setSelectedItem(implementation); 282 | } 283 | 284 | public String getImplementation() { 285 | return (String) implementationComboBox.getSelectedItem(); 286 | } 287 | 288 | public void setMessageBacklog(String messageBacklog) { 289 | messageBacklogTextField.setText(messageBacklog); 290 | } 291 | 292 | public String getMessageBacklog() { 293 | return messageBacklogTextField.getText(); 294 | } 295 | 296 | /** 297 | * @return the attributePanel 298 | */ 299 | public ArgumentsPanel getAttributePanel() { 300 | return attributePanel; 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/functional/samplers/websocket/ServiceSocket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.samplers.websocket; 6 | 7 | import java.io.IOException; 8 | import java.util.Deque; 9 | import java.util.Iterator; 10 | import java.util.Queue; 11 | import java.util.concurrent.ConcurrentLinkedQueue; 12 | import java.util.concurrent.CountDownLatch; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | import org.apache.log.Logger; 16 | 17 | import java.util.regex.Pattern; 18 | 19 | import org.apache.jmeter.engine.util.CompoundVariable; 20 | import org.apache.jorphan.logging.LoggingManager; 21 | import org.eclipse.jetty.websocket.api.Session; 22 | import org.eclipse.jetty.websocket.api.StatusCode; 23 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; 24 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; 25 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; 26 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; 27 | import org.eclipse.jetty.websocket.api.annotations.WebSocket; 28 | import org.eclipse.jetty.websocket.api.extensions.Frame; 29 | import org.eclipse.jetty.websocket.client.WebSocketClient; 30 | 31 | /** 32 | * 33 | * @author Maciej Zaleski 34 | */ 35 | @WebSocket(maxTextMessageSize = 256 * 1024 * 1024) 36 | public class ServiceSocket { 37 | 38 | protected final WebSocketSampler parent; 39 | protected WebSocketClient client; 40 | private static final Logger log = LoggingManager.getLoggerForClass(); 41 | protected Queue<String> responseBacklog = new ConcurrentLinkedQueue<>(); 42 | protected Integer error = 0; 43 | protected StringBuffer logMessage = new StringBuffer(); 44 | protected CountDownLatch openLatch = new CountDownLatch(1); 45 | protected CountDownLatch closeLatch = new CountDownLatch(1); 46 | protected Session session = null; 47 | protected String responsePattern; 48 | protected String disconnectPattern; 49 | protected int messageCounter = 1; 50 | protected Pattern responseExpression; 51 | protected Pattern disconnectExpression; 52 | protected boolean connected = false; 53 | 54 | public ServiceSocket(WebSocketSampler parent, WebSocketClient client) { 55 | this.parent = parent; 56 | this.client = client; 57 | 58 | setResponsePattern(parent.getResponsePattern()); 59 | setDisconnectPattern(parent.getCloseConncectionPattern()); 60 | logMessage.append("\n\n[Execution Flow]\n"); 61 | logMessage.append(" - Opening new connection\n"); 62 | } 63 | 64 | @OnWebSocketMessage 65 | public void onMessage(String msg) { 66 | synchronized (parent) { 67 | log.debug("Received message: " + msg); 68 | String length = " (" + msg.length() + " bytes)"; 69 | logMessage.append(" - Received message #").append(messageCounter).append(length); 70 | addResponseMessage("[Message " + (messageCounter++) + "]\n" + msg + "\n\n"); 71 | 72 | if (responseExpression == null || responseExpression.matcher(msg).find()) { 73 | logMessage.append("; matched response pattern").append("\n"); 74 | closeLatch.countDown(); 75 | } else if (!disconnectPattern.isEmpty() && disconnectExpression.matcher(msg).find()) { 76 | logMessage.append("; matched connection close pattern").append("\n"); 77 | closeLatch.countDown(); 78 | close(StatusCode.NORMAL, "JMeter closed session."); 79 | } else { 80 | logMessage.append("; didn't match any pattern").append("\n"); 81 | } 82 | } 83 | } 84 | 85 | @OnWebSocketFrame 86 | public void onFrame(Frame frame) { 87 | synchronized (parent) { 88 | log.debug("Received frame: " + frame.getPayload() + " " 89 | + frame.getType().name()); 90 | String length = " (" + frame.getPayloadLength() + " bytes)"; 91 | logMessage.append(" - Received frame #").append(messageCounter) 92 | .append(length); 93 | String frameTxt = new String(frame.getPayload().array()); 94 | addResponseMessage("[Frame " + (messageCounter++) + "]\n" 95 | + frameTxt + "\n\n"); 96 | 97 | if (responseExpression == null 98 | || responseExpression.matcher(frameTxt).find()) { 99 | logMessage.append("; matched response pattern").append("\n"); 100 | closeLatch.countDown(); 101 | } else if (!disconnectPattern.isEmpty() 102 | && disconnectExpression.matcher(frameTxt).find()) { 103 | logMessage.append("; matched connection close pattern").append( 104 | "\n"); 105 | closeLatch.countDown(); 106 | close(StatusCode.NORMAL, "JMeter closed session."); 107 | } else { 108 | logMessage.append("; didn't match any pattern").append("\n"); 109 | } 110 | } 111 | } 112 | 113 | @OnWebSocketConnect 114 | public void onOpen(Session session) { 115 | logMessage.append(" - WebSocket conection has been opened").append("\n"); 116 | log.debug("Connect " + session.isOpen()); 117 | this.session = session; 118 | connected = true; 119 | openLatch.countDown(); 120 | } 121 | 122 | @OnWebSocketClose 123 | public void onClose(int statusCode, String reason) { 124 | if (statusCode != 1000) { 125 | log.error("Disconnect " + statusCode + ": " + reason); 126 | logMessage.append(" - WebSocket conection closed unexpectedly by the server: [").append(statusCode).append("] ").append(reason).append("\n"); 127 | error = statusCode; 128 | } else { 129 | logMessage.append(" - WebSocket conection has been successfully closed by the server").append("\n"); 130 | log.debug("Disconnect " + statusCode + ": " + reason); 131 | } 132 | 133 | //Notify connection opening and closing latches of the closed connection 134 | openLatch.countDown(); 135 | closeLatch.countDown(); 136 | connected = false; 137 | } 138 | 139 | /** 140 | * @return response message made of messages saved in the responseBacklog cache 141 | */ 142 | public String getResponseMessage() { 143 | String responseMessage = ""; 144 | 145 | //Iterate through response messages saved in the responseBacklog cache 146 | Iterator<String> iterator = responseBacklog.iterator(); 147 | while (iterator.hasNext()) { 148 | responseMessage += iterator.next(); 149 | } 150 | 151 | return responseMessage; 152 | } 153 | 154 | public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException { 155 | logMessage.append(" - Waiting for messages for ").append(duration).append(" ").append(unit.toString()).append("\n"); 156 | boolean res = this.closeLatch.await(duration, unit); 157 | 158 | if (!parent.isStreamingConnection()) { 159 | close(StatusCode.NORMAL, "JMeter closed session."); 160 | } else { 161 | logMessage.append(" - Leaving streaming connection open").append("\n"); 162 | } 163 | 164 | return res; 165 | } 166 | 167 | public boolean awaitOpen(int duration, TimeUnit unit) throws InterruptedException { 168 | logMessage.append(" - Waiting for the server connection for ").append(duration).append(" ").append(unit.toString()).append("\n"); 169 | boolean res = this.openLatch.await(duration, unit); 170 | 171 | if (connected) { 172 | logMessage.append(" - Connection established").append("\n"); 173 | } else { 174 | logMessage.append(" - Cannot connect to the remote server").append("\n"); 175 | } 176 | 177 | return res; 178 | } 179 | 180 | /** 181 | * @return the session 182 | */ 183 | public Session getSession() { 184 | return session; 185 | } 186 | 187 | public void sendMessage(String message) throws IOException { 188 | session.getRemote().sendString(message); 189 | } 190 | 191 | public void close() { 192 | close(StatusCode.NORMAL, "JMeter closed session."); 193 | } 194 | 195 | public void close(int statusCode, String statusText) { 196 | //Closing WebSocket session 197 | if (session != null) { 198 | session.close(statusCode, statusText); 199 | logMessage.append(" - WebSocket session closed by the client").append("\n"); 200 | } else { 201 | logMessage.append(" - WebSocket session wasn't started (...that's odd)").append("\n"); 202 | } 203 | 204 | 205 | //Stoping WebSocket client; thanks m0ro 206 | try { 207 | client.stop(); 208 | logMessage.append(" - WebSocket client closed by the client").append("\n"); 209 | } catch (Exception e) { 210 | logMessage.append(" - WebSocket client wasn't started (...that's odd)").append("\n"); 211 | } 212 | } 213 | 214 | /** 215 | * @return the error 216 | */ 217 | public Integer getError() { 218 | return error; 219 | } 220 | 221 | /** 222 | * @return the logMessage 223 | */ 224 | public String getLogMessage() { 225 | logMessage.append("\n\n[Variables]\n"); 226 | logMessage.append(" - Message count: ").append(messageCounter - 1).append("\n"); 227 | 228 | return logMessage.toString(); 229 | } 230 | 231 | public void log(String message) { 232 | logMessage.append(message); 233 | } 234 | 235 | /** 236 | * Resets the patterns used to end a sample 237 | * @param newResponsePattern the new response pattern to use 238 | */ 239 | protected void setResponsePattern(String newResponsePattern) { 240 | // Evaluate response matching patterns in case thay contain JMeter variables (i.e. ${var}) 241 | responsePattern = new CompoundVariable(newResponsePattern).execute(); 242 | initializeResponsePattern(); 243 | } 244 | 245 | private void initializeResponsePattern() { 246 | try { 247 | logMessage.append(" - Using response message pattern \"").append(responsePattern).append("\"\n"); 248 | responseExpression = (responsePattern != null || !responsePattern.isEmpty()) ? Pattern.compile(responsePattern) : null; 249 | } catch (Exception ex) { 250 | logMessage.append(" - Invalid response message regular expression pattern: ").append(ex.getLocalizedMessage()).append("\n"); 251 | log.error("Invalid response message regular expression pattern: " + ex.getLocalizedMessage()); 252 | responseExpression = null; 253 | } 254 | } 255 | 256 | /** 257 | * Resets the patterns used to close the connection 258 | * @param newDisconnectPattern the new disconnect pattern to use 259 | */ 260 | protected void setDisconnectPattern(String newDisconnectPattern) { 261 | // Evaluate response matching patterns in case thay contain JMeter variables (i.e. ${var}) 262 | disconnectPattern = new CompoundVariable(newDisconnectPattern).execute(); 263 | initializeDisconnectPattern(); 264 | } 265 | 266 | private void initializeDisconnectPattern() { 267 | try { 268 | logMessage.append(" - Using disconnect pattern \"").append(disconnectPattern).append("\"\n"); 269 | disconnectExpression = (disconnectPattern != null || !disconnectPattern.isEmpty()) ? Pattern.compile(disconnectPattern) : null; 270 | } catch (Exception ex) { 271 | logMessage.append(" - Invalid disconnect regular expression pattern: ").append(ex.getLocalizedMessage()).append("\n"); 272 | log.error("Invalid disconnect regular regular expression pattern: " + ex.getLocalizedMessage()); 273 | disconnectExpression = null; 274 | } 275 | } 276 | 277 | /** 278 | * @return the connected 279 | */ 280 | public boolean isConnected() { 281 | return connected; 282 | } 283 | 284 | public void initialize() { 285 | logMessage = new StringBuffer(); 286 | logMessage.append("\n\n[Execution Flow]\n"); 287 | logMessage.append(" - Reusing exising connection\n"); 288 | error = 0; 289 | 290 | this.closeLatch = new CountDownLatch(1); 291 | } 292 | 293 | private void addResponseMessage(String message) { 294 | int messageBacklog; 295 | try { 296 | messageBacklog = Integer.parseInt(parent.getMessageBacklog()); 297 | } catch (Exception ex) { 298 | logMessage.append(" - Message backlog value not set; using default ").append(WebSocketSampler.MESSAGE_BACKLOG_COUNT).append("\n"); 299 | messageBacklog = WebSocketSampler.MESSAGE_BACKLOG_COUNT; 300 | } 301 | 302 | while (responseBacklog.size() >= messageBacklog) { 303 | responseBacklog.poll(); 304 | } 305 | responseBacklog.add(message); 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketApplicationRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.controler.websocketapp; 6 | 7 | import JMeter.plugins.functional.samplers.websocket.*; 8 | import java.awt.Color; 9 | import org.apache.jmeter.config.gui.ArgumentsPanel; 10 | import org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel; 11 | import org.apache.jorphan.logging.LoggingManager; 12 | import org.apache.log.Logger; 13 | 14 | /** 15 | * 16 | * @author Maciej Zaleski 17 | */ 18 | public class WebSocketApplicationRequest extends javax.swing.JPanel { 19 | private static final Logger log = LoggingManager.getLoggerForClass(); 20 | private HTTPArgumentsPanel attributePanel; 21 | 22 | /** 23 | * Creates new form WebSocketSamplerPanel 24 | */ 25 | public WebSocketApplicationRequest() { 26 | initComponents(); 27 | 28 | attributePanel = new HTTPArgumentsPanel(); 29 | querystringAttributesPanel.add(attributePanel); 30 | } 31 | 32 | /** 33 | * This method is called from within the constructor to initialize the form. 34 | * WARNING: Do NOT modify this code. The content of this method is always 35 | * regenerated by the Form Editor. 36 | */ 37 | @SuppressWarnings("unchecked") 38 | // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents 39 | private void initComponents() { 40 | 41 | jPanel4 = new javax.swing.JPanel(); 42 | jScrollPane1 = new javax.swing.JScrollPane(); 43 | requestPayloadEditorPane = new javax.swing.JEditorPane(); 44 | jPanel1 = new javax.swing.JPanel(); 45 | jPanel2 = new javax.swing.JPanel(); 46 | jScrollPane2 = new javax.swing.JScrollPane(); 47 | jTable1 = new javax.swing.JTable(); 48 | 49 | jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Client Request")); 50 | 51 | jScrollPane1.setViewportView(requestPayloadEditorPane); 52 | 53 | javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 54 | jPanel1.setLayout(jPanel1Layout); 55 | jPanel1Layout.setHorizontalGroup( 56 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 57 | .addGap(0, 0, Short.MAX_VALUE) 58 | ); 59 | jPanel1Layout.setVerticalGroup( 60 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 61 | .addGap(0, 135, Short.MAX_VALUE) 62 | ); 63 | 64 | javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); 65 | jPanel4.setLayout(jPanel4Layout); 66 | jPanel4Layout.setHorizontalGroup( 67 | jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 68 | .addGroup(jPanel4Layout.createSequentialGroup() 69 | .addContainerGap() 70 | .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 71 | .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 493, Short.MAX_VALUE) 72 | .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 73 | .addContainerGap()) 74 | ); 75 | jPanel4Layout.setVerticalGroup( 76 | jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 77 | .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() 78 | .addContainerGap() 79 | .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 80 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 81 | .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) 82 | .addContainerGap()) 83 | ); 84 | 85 | jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Response handlers")); 86 | 87 | jTable1.setModel(new javax.swing.table.DefaultTableModel( 88 | new Object [][] { 89 | {"Successfull", "Quote received", "trade", new Boolean(true)}, 90 | {"Market closed", "Quote failed", "quote", new Boolean(true)}, 91 | {"System unavailable", "Quote failed", "quote", new Boolean(true)} 92 | }, 93 | new String [] { 94 | "Handler name", "Response handler", "Application state", "Enabled" 95 | } 96 | ) { 97 | Class[] types = new Class [] { 98 | java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class 99 | }; 100 | 101 | public Class getColumnClass(int columnIndex) { 102 | return types [columnIndex]; 103 | } 104 | }); 105 | jScrollPane2.setViewportView(jTable1); 106 | 107 | javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); 108 | jPanel2.setLayout(jPanel2Layout); 109 | jPanel2Layout.setHorizontalGroup( 110 | jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 111 | .addGroup(jPanel2Layout.createSequentialGroup() 112 | .addContainerGap() 113 | .addComponent(jScrollPane2)) 114 | ); 115 | jPanel2Layout.setVerticalGroup( 116 | jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 117 | .addGroup(jPanel2Layout.createSequentialGroup() 118 | .addGap(19, 19, 19) 119 | .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 155, Short.MAX_VALUE) 120 | .addContainerGap()) 121 | ); 122 | 123 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 124 | this.setLayout(layout); 125 | layout.setHorizontalGroup( 126 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 127 | .addGroup(layout.createSequentialGroup() 128 | .addContainerGap() 129 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 130 | .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 131 | .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 132 | .addContainerGap()) 133 | ); 134 | layout.setVerticalGroup( 135 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 136 | .addGroup(layout.createSequentialGroup() 137 | .addContainerGap() 138 | .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 139 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 140 | .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 141 | .addContainerGap()) 142 | ); 143 | }// </editor-fold>//GEN-END:initComponents 144 | // Variables declaration - do not modify//GEN-BEGIN:variables 145 | private javax.swing.JPanel jPanel1; 146 | private javax.swing.JPanel jPanel2; 147 | private javax.swing.JPanel jPanel4; 148 | private javax.swing.JScrollPane jScrollPane1; 149 | private javax.swing.JScrollPane jScrollPane2; 150 | private javax.swing.JTable jTable1; 151 | private javax.swing.JEditorPane requestPayloadEditorPane; 152 | // End of variables declaration//GEN-END:variables 153 | 154 | public void initFields() { 155 | } 156 | 157 | public void setCloseConncectionPattern(String closeConncectionPattern) { 158 | closeConncectionPatternTextField.setText(closeConncectionPattern); 159 | } 160 | 161 | public String getCloseConncectionPattern() { 162 | return closeConncectionPatternTextField.getText(); 163 | } 164 | 165 | public void setConnectionId(String connectionId) { 166 | connectionIdTextField.setText(connectionId); 167 | } 168 | 169 | public String getConnectionId() { 170 | return connectionIdTextField.getText(); 171 | } 172 | 173 | public void setContentEncoding(String contentEncoding) { 174 | contentEncodingTextField.setText(contentEncoding); 175 | } 176 | 177 | public String getContentEncoding() { 178 | return contentEncodingTextField.getText(); 179 | } 180 | 181 | public void setContextPath(String contextPath) { 182 | contextPathTextField.setText(contextPath); 183 | } 184 | 185 | public String getContextPath() { 186 | return contextPathTextField.getText(); 187 | } 188 | 189 | public void setProtocol(String protocol) { 190 | protocolTextField.setText(protocol); 191 | } 192 | 193 | public String getProtocol() { 194 | return protocolTextField.getText(); 195 | } 196 | 197 | public void setProxyAddress(String proxyAddress) { 198 | proxyAddressTextField.setText(proxyAddress); 199 | } 200 | 201 | public String getProxyAddress() { 202 | return proxyAddressTextField.getText(); 203 | } 204 | 205 | public void setProxyPassword(String proxyPassword) { 206 | proxyPasswordTextField.setText(proxyPassword); 207 | } 208 | 209 | public String getProxyPassword() { 210 | return proxyPasswordTextField.getText(); 211 | } 212 | 213 | public void setProxyPort(String proxyPort) { 214 | proxyPortTextField.setText(proxyPort); 215 | } 216 | 217 | public String getProxyPort() { 218 | return proxyPortTextField.getText(); 219 | } 220 | 221 | public void setProxyUsername(String proxyUsername) { 222 | proxyUsernameTextField.setText(proxyUsername); 223 | } 224 | 225 | public String getProxyUsername() { 226 | return proxyUsernameTextField.getText(); 227 | } 228 | 229 | public void setResponsePattern(String responsePattern) { 230 | responsePatternTextField.setText(responsePattern); 231 | } 232 | 233 | public String getResponsePattern() { 234 | return responsePatternTextField.getText(); 235 | } 236 | 237 | public void setResponseTimeout(String responseTimeout) { 238 | responseTimeoutTextField.setText(responseTimeout); 239 | } 240 | 241 | public String getResponseTimeout() { 242 | return responseTimeoutTextField.getText(); 243 | } 244 | 245 | public void setConnectionTimeout(String connectionTimeout) { 246 | connectionTimeoutTextField.setText(connectionTimeout); 247 | } 248 | 249 | public String getConnectionTimeout() { 250 | return connectionTimeoutTextField.getText(); 251 | } 252 | 253 | public void setServerAddress(String serverAddress) { 254 | serverAddressTextField.setText(serverAddress); 255 | } 256 | 257 | public String getServerAddress() { 258 | return serverAddressTextField.getText(); 259 | } 260 | 261 | public void setServerPort(String serverPort) { 262 | serverPortTextField.setText(serverPort); 263 | } 264 | 265 | public String getServerPort() { 266 | return serverPortTextField.getText(); 267 | } 268 | 269 | public void setRequestPayload(String requestPayload) { 270 | requestPayloadEditorPane.setText(requestPayload); 271 | } 272 | 273 | public String getRequestPayload() { 274 | return requestPayloadEditorPane.getText(); 275 | } 276 | 277 | public void setStreamingConnection(Boolean streamingConnection) { 278 | streamingConnectionCheckBox.setSelected(streamingConnection); 279 | } 280 | 281 | public Boolean isStreamingConnection() { 282 | return streamingConnectionCheckBox.isSelected(); 283 | } 284 | 285 | public void setIgnoreSslErrors(Boolean ignoreSslErrors) { 286 | ignoreSslErrorsCheckBox.setSelected(ignoreSslErrors); 287 | } 288 | 289 | public Boolean isIgnoreSslErrors() { 290 | return ignoreSslErrorsCheckBox.isSelected(); 291 | } 292 | 293 | public void setImplementation(String implementation) { 294 | implementationComboBox.setSelectedItem(implementation); 295 | } 296 | 297 | public String getImplementation() { 298 | return (String) implementationComboBox.getSelectedItem(); 299 | } 300 | 301 | public void setMessageBacklog(String messageBacklog) { 302 | messageBacklogTextField.setText(messageBacklog); 303 | } 304 | 305 | public String getMessageBacklog() { 306 | return messageBacklogTextField.getText(); 307 | } 308 | 309 | /** 310 | * @return the attributePanel 311 | */ 312 | public ArgumentsPanel getAttributePanel() { 313 | return attributePanel; 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketSampler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.controler.websocketapp; 6 | 7 | import JMeter.plugins.functional.samplers.websocket.*; 8 | import java.io.IOException; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.apache.jmeter.config.Argument; 11 | import org.apache.jmeter.config.Arguments; 12 | import org.apache.jmeter.protocol.http.util.EncoderCache; 13 | import org.apache.jmeter.protocol.http.util.HTTPArgument; 14 | import org.apache.jmeter.protocol.http.util.HTTPConstants; 15 | import org.apache.jmeter.samplers.AbstractSampler; 16 | import org.apache.jmeter.samplers.Entry; 17 | import org.apache.jmeter.samplers.SampleResult; 18 | import org.apache.jmeter.testelement.TestElement; 19 | import org.apache.jmeter.testelement.property.*; 20 | import org.apache.jorphan.logging.LoggingManager; 21 | import org.apache.jorphan.util.JOrphanUtils; 22 | import org.apache.log.Logger; 23 | 24 | 25 | import java.io.UnsupportedEncodingException; 26 | import java.net.URI; 27 | import java.net.URISyntaxException; 28 | import java.util.Map; 29 | import java.util.concurrent.ConcurrentHashMap; 30 | import java.util.concurrent.TimeUnit; 31 | import org.apache.jmeter.testelement.TestStateListener; 32 | import org.eclipse.jetty.util.ssl.SslContextFactory; 33 | import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; 34 | import org.eclipse.jetty.websocket.client.WebSocketClient; 35 | 36 | /** 37 | * 38 | * @author Maciej Zaleski 39 | */ 40 | public class WebSocketSampler extends AbstractSampler implements TestStateListener { 41 | private static final Logger log = LoggingManager.getLoggerForClass(); 42 | 43 | private static final String ARG_VAL_SEP = "="; // $NON-NLS-1$ 44 | private static final String QRY_SEP = "&"; // $NON-NLS-1$ 45 | private static final String WS_PREFIX = "ws://"; // $NON-NLS-1$ 46 | private static final String WSS_PREFIX = "wss://"; // $NON-NLS-1$ 47 | private static final String DEFAULT_PROTOCOL = "ws"; 48 | 49 | private static Map<String, ServiceSocket> connectionList; 50 | 51 | public WebSocketSampler() { 52 | super(); 53 | setName("WebSocket sampler"); 54 | } 55 | 56 | private ServiceSocket getConnectionSocket() throws URISyntaxException, Exception { 57 | URI uri = getUri(); 58 | 59 | String connectionId = getThreadName() + getConnectionId(); 60 | ServiceSocket socket; 61 | WebSocketClient webSocketClient; 62 | if (isStreamingConnection()) { 63 | if (connectionList.containsKey(connectionId)) { 64 | socket = connectionList.get(connectionId); 65 | socket.initialize(); 66 | return socket; 67 | } else { 68 | socket = new ServiceSocket(this); 69 | connectionList.put(connectionId, socket); 70 | } 71 | } else { 72 | socket = new ServiceSocket(this); 73 | } 74 | 75 | SslContextFactory sslContexFactory = new SslContextFactory(); 76 | sslContexFactory.setTrustAll(isIgnoreSslErrors()); 77 | webSocketClient = new WebSocketClient(sslContexFactory); 78 | 79 | webSocketClient.start(); 80 | ClientUpgradeRequest request = new ClientUpgradeRequest(); 81 | webSocketClient.connect(socket, uri, request); 82 | 83 | int connectionTimeout = Integer.parseInt(getConnectionTimeout()); 84 | socket.awaitOpen(connectionTimeout, TimeUnit.MILLISECONDS); 85 | 86 | return socket; 87 | } 88 | 89 | @Override 90 | public SampleResult sample(Entry entry) { 91 | ServiceSocket socket = null; 92 | SampleResult sampleResult = new SampleResult(); 93 | sampleResult.setSampleLabel(getName()); 94 | sampleResult.setDataEncoding(getContentEncoding()); 95 | 96 | StringBuilder errorList = new StringBuilder(); 97 | errorList.append("\n\n[Problems]\n"); 98 | 99 | boolean isOK = false; 100 | 101 | String payloadMessage = getRequestPayload(); 102 | sampleResult.setSamplerData(payloadMessage); 103 | sampleResult.sampleStart(); 104 | 105 | try { 106 | socket = getConnectionSocket(); 107 | if (socket == null) { 108 | sampleResult.setResponseCode("500"); 109 | sampleResult.setSuccessful(false); 110 | sampleResult.sampleEnd(); 111 | sampleResult.setResponseMessage(errorList.toString()); 112 | errorList.append(" - Connection couldn't be opened").append("\n"); 113 | return sampleResult; 114 | } 115 | 116 | if (!payloadMessage.isEmpty()) { 117 | socket.sendMessage(payloadMessage); 118 | } 119 | 120 | int responseTimeout = Integer.parseInt(getResponseTimeout()); 121 | socket.awaitClose(responseTimeout, TimeUnit.MILLISECONDS); 122 | 123 | 124 | if (socket.getResponseMessage() == null || socket.getResponseMessage().isEmpty()) { 125 | sampleResult.setResponseCode("204"); 126 | } 127 | 128 | if (socket.getError() != 0) { 129 | isOK = false; 130 | sampleResult.setResponseCode(socket.getError().toString()); 131 | } else { 132 | sampleResult.setResponseCodeOK(); 133 | isOK = true; 134 | } 135 | 136 | sampleResult.setResponseData(socket.getResponseMessage(), getContentEncoding()); 137 | 138 | } catch (URISyntaxException e) { 139 | errorList.append(" - Invalid URI syntax: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 140 | } catch (IOException e) { 141 | errorList.append(" - IO Exception: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 142 | } catch (NumberFormatException e) { 143 | errorList.append(" - Cannot parse number: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 144 | } catch (InterruptedException e) { 145 | errorList.append(" - Execution interrupted: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 146 | } catch (Exception e) { 147 | errorList.append(" - Unexpected error: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 148 | } 149 | 150 | sampleResult.sampleEnd(); 151 | sampleResult.setSuccessful(isOK); 152 | 153 | String logMessage = (socket != null) ? socket.getLogMessage() : ""; 154 | sampleResult.setResponseMessage(logMessage + errorList); 155 | return sampleResult; 156 | } 157 | 158 | @Override 159 | public void setName(String name) { 160 | if (name != null) { 161 | setProperty(TestElement.NAME, name); 162 | } 163 | } 164 | 165 | @Override 166 | public String getName() { 167 | return getPropertyAsString(TestElement.NAME); 168 | } 169 | 170 | @Override 171 | public void setComment(String comment) { 172 | setProperty(new StringProperty(TestElement.COMMENTS, comment)); 173 | } 174 | 175 | @Override 176 | public String getComment() { 177 | return getProperty(TestElement.COMMENTS).getStringValue(); 178 | } 179 | 180 | public URI getUri() throws URISyntaxException { 181 | String path = this.getContextPath(); 182 | // Hack to allow entire URL to be provided in host field 183 | if (path.startsWith(WS_PREFIX) 184 | || path.startsWith(WSS_PREFIX)) { 185 | return new URI(path); 186 | } 187 | String domain = getServerAddress(); 188 | String protocol = getProtocol(); 189 | // HTTP URLs must be absolute, allow file to be relative 190 | if (!path.startsWith("/")) { // $NON-NLS-1$ 191 | path = "/" + path; // $NON-NLS-1$ 192 | } 193 | 194 | String queryString = getQueryString(getContentEncoding()); 195 | if (isProtocolDefaultPort()) { 196 | return new URI(protocol, null, domain, -1, path, queryString, null); 197 | } 198 | return new URI(protocol, null, domain, Integer.parseInt(getServerPort()), path, queryString, null); 199 | } 200 | 201 | /** 202 | * Tell whether the default port for the specified protocol is used 203 | * 204 | * @return true if the default port number for the protocol is used, false 205 | * otherwise 206 | */ 207 | public boolean isProtocolDefaultPort() { 208 | final int port = Integer.parseInt(getServerPort()); 209 | final String protocol = getProtocol(); 210 | return ("ws".equalsIgnoreCase(protocol) && port == HTTPConstants.DEFAULT_HTTP_PORT) 211 | || ("wss".equalsIgnoreCase(protocol) && port == HTTPConstants.DEFAULT_HTTPS_PORT); 212 | } 213 | 214 | public String getServerPort() { 215 | final String port_s = getPropertyAsString("serverPort", "0"); 216 | Integer port; 217 | String protocol = getProtocol(); 218 | 219 | try { 220 | port = Integer.parseInt(port_s); 221 | } catch (Exception ex) { 222 | port = 0; 223 | } 224 | 225 | if (port == 0) { 226 | if ("wss".equalsIgnoreCase(protocol)) { 227 | return String.valueOf(HTTPConstants.DEFAULT_HTTPS_PORT); 228 | } else if ("ws".equalsIgnoreCase(protocol)) { 229 | return String.valueOf(HTTPConstants.DEFAULT_HTTP_PORT); 230 | } 231 | } 232 | return port.toString(); 233 | } 234 | 235 | public void setServerPort(String port) { 236 | setProperty("serverPort", port); 237 | } 238 | 239 | public String getResponseTimeout() { 240 | return getPropertyAsString("responseTimeout", "20000"); 241 | } 242 | 243 | public void setResponseTimeout(String responseTimeout) { 244 | setProperty("responseTimeout", responseTimeout); 245 | } 246 | 247 | 248 | public String getConnectionTimeout() { 249 | return getPropertyAsString("connectionTimeout", "5000"); 250 | } 251 | 252 | public void setConnectionTimeout(String connectionTimeout) { 253 | setProperty("connectionTimeout", connectionTimeout); 254 | } 255 | 256 | public void setProtocol(String protocol) { 257 | setProperty("protocol", protocol); 258 | } 259 | 260 | public String getProtocol() { 261 | String protocol = getPropertyAsString("protocol"); 262 | if (protocol == null || protocol.isEmpty()) { 263 | return DEFAULT_PROTOCOL; 264 | } 265 | return protocol; 266 | } 267 | 268 | public void setServerAddress(String serverAddress) { 269 | setProperty("serverAddress", serverAddress); 270 | } 271 | 272 | public String getServerAddress() { 273 | return getPropertyAsString("serverAddress"); 274 | } 275 | 276 | 277 | public void setImplementation(String implementation) { 278 | setProperty("implementation", implementation); 279 | } 280 | 281 | public String getImplementation() { 282 | return getPropertyAsString("implementation"); 283 | } 284 | 285 | public void setContextPath(String contextPath) { 286 | setProperty("contextPath", contextPath); 287 | } 288 | 289 | public String getContextPath() { 290 | return getPropertyAsString("contextPath"); 291 | } 292 | 293 | public void setContentEncoding(String contentEncoding) { 294 | setProperty("contentEncoding", contentEncoding); 295 | } 296 | 297 | public String getContentEncoding() { 298 | return getPropertyAsString("contentEncoding", "UTF-8"); 299 | } 300 | 301 | public void setRequestPayload(String requestPayload) { 302 | setProperty("requestPayload", requestPayload); 303 | } 304 | 305 | public String getRequestPayload() { 306 | return getPropertyAsString("requestPayload"); 307 | } 308 | 309 | public void setIgnoreSslErrors(Boolean ignoreSslErrors) { 310 | setProperty("ignoreSslErrors", ignoreSslErrors); 311 | } 312 | 313 | public Boolean isIgnoreSslErrors() { 314 | return getPropertyAsBoolean("ignoreSslErrors"); 315 | } 316 | 317 | public void setStreamingConnection(Boolean streamingConnection) { 318 | setProperty("streamingConnection", streamingConnection); 319 | } 320 | 321 | public Boolean isStreamingConnection() { 322 | return getPropertyAsBoolean("streamingConnection"); 323 | } 324 | 325 | public void setConnectionId(String connectionId) { 326 | setProperty("connectionId", connectionId); 327 | } 328 | 329 | public String getConnectionId() { 330 | return getPropertyAsString("connectionId"); 331 | } 332 | 333 | public void setResponsePattern(String responsePattern) { 334 | setProperty("responsePattern", responsePattern); 335 | } 336 | 337 | public String getResponsePattern() { 338 | return getPropertyAsString("responsePattern"); 339 | } 340 | 341 | public void setCloseConncectionPattern(String closeConncectionPattern) { 342 | setProperty("closeConncectionPattern", closeConncectionPattern); 343 | } 344 | 345 | public String getCloseConncectionPattern() { 346 | return getPropertyAsString("closeConncectionPattern"); 347 | } 348 | 349 | public void setProxyAddress(String proxyAddress) { 350 | setProperty("proxyAddress", proxyAddress); 351 | } 352 | 353 | public String getProxyAddress() { 354 | return getPropertyAsString("proxyAddress"); 355 | } 356 | 357 | public void setProxyPassword(String proxyPassword) { 358 | setProperty("proxyPassword", proxyPassword); 359 | } 360 | 361 | public String getProxyPassword() { 362 | return getPropertyAsString("proxyPassword"); 363 | } 364 | 365 | public void setProxyPort(String proxyPort) { 366 | setProperty("proxyPort", proxyPort); 367 | } 368 | 369 | public String getProxyPort() { 370 | return getPropertyAsString("proxyPort"); 371 | } 372 | 373 | public void setProxyUsername(String proxyUsername) { 374 | setProperty("proxyUsername", proxyUsername); 375 | } 376 | 377 | public String getProxyUsername() { 378 | return getPropertyAsString("proxyUsername"); 379 | } 380 | 381 | public void setMessageBacklog(String messageBacklog) { 382 | setProperty("messageBacklog", messageBacklog); 383 | } 384 | 385 | public String getMessageBacklog() { 386 | return getPropertyAsString("messageBacklog", "3"); 387 | } 388 | 389 | 390 | 391 | public String getQueryString(String contentEncoding) { 392 | // Check if the sampler has a specified content encoding 393 | if (JOrphanUtils.isBlank(contentEncoding)) { 394 | // We use the encoding which should be used according to the HTTP spec, which is UTF-8 395 | contentEncoding = EncoderCache.URL_ARGUMENT_ENCODING; 396 | } 397 | StringBuilder buf = new StringBuilder(); 398 | PropertyIterator iter = getQueryStringParameters().iterator(); 399 | boolean first = true; 400 | while (iter.hasNext()) { 401 | HTTPArgument item = null; 402 | Object objectValue = iter.next().getObjectValue(); 403 | try { 404 | item = (HTTPArgument) objectValue; 405 | } catch (ClassCastException e) { 406 | item = new HTTPArgument((Argument) objectValue); 407 | } 408 | final String encodedName = item.getEncodedName(); 409 | if (encodedName.length() == 0) { 410 | continue; // Skip parameters with a blank name (allows use of optional variables in parameter lists) 411 | } 412 | if (!first) { 413 | buf.append(QRY_SEP); 414 | } else { 415 | first = false; 416 | } 417 | buf.append(encodedName); 418 | if (item.getMetaData() == null) { 419 | buf.append(ARG_VAL_SEP); 420 | } else { 421 | buf.append(item.getMetaData()); 422 | } 423 | 424 | // Encode the parameter value in the specified content encoding 425 | try { 426 | buf.append(item.getEncodedValue(contentEncoding)); 427 | } catch (UnsupportedEncodingException e) { 428 | log.warn("Unable to encode parameter in encoding " + contentEncoding + ", parameter value not included in query string"); 429 | } 430 | } 431 | return buf.toString(); 432 | } 433 | 434 | public void setQueryStringParameters(Arguments queryStringParameters) { 435 | setProperty(new TestElementProperty("queryStringParameters", queryStringParameters)); 436 | } 437 | 438 | public Arguments getQueryStringParameters() { 439 | Arguments args = (Arguments) getProperty("queryStringParameters").getObjectValue(); 440 | return args; 441 | } 442 | 443 | 444 | @Override 445 | public void testStarted() { 446 | testStarted("unknown"); 447 | } 448 | 449 | @Override 450 | public void testStarted(String host) { 451 | connectionList = new ConcurrentHashMap<String, ServiceSocket>(); 452 | } 453 | 454 | @Override 455 | public void testEnded() { 456 | testEnded("unknown"); 457 | } 458 | 459 | @Override 460 | public void testEnded(String host) { 461 | for (ServiceSocket socket : connectionList.values()) { 462 | socket.close(); 463 | } 464 | } 465 | 466 | 467 | 468 | } 469 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketApplicationConfig.form: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" ?> 2 | 3 | <Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> 4 | <AuxValues> 5 | <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> 6 | <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> 7 | <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> 8 | <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> 9 | <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> 10 | <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> 11 | <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> 12 | <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> 13 | <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> 14 | </AuxValues> 15 | 16 | <Layout> 17 | <DimensionLayout dim="0"> 18 | <Group type="103" groupAlignment="0" attributes="0"> 19 | <Group type="102" attributes="0"> 20 | <EmptySpace max="-2" attributes="0"/> 21 | <Group type="103" groupAlignment="0" attributes="0"> 22 | <Component id="jPanel3" max="32767" attributes="0"/> 23 | <Group type="102" alignment="0" attributes="0"> 24 | <Component id="jPanel1" max="32767" attributes="0"/> 25 | <EmptySpace min="-2" max="-2" attributes="0"/> 26 | <Component id="jPanel2" max="32767" attributes="0"/> 27 | </Group> 28 | <Component id="jPanel6" max="32767" attributes="0"/> 29 | </Group> 30 | <EmptySpace max="-2" attributes="0"/> 31 | </Group> 32 | </Group> 33 | </DimensionLayout> 34 | <DimensionLayout dim="1"> 35 | <Group type="103" groupAlignment="0" attributes="0"> 36 | <Group type="102" alignment="0" attributes="0"> 37 | <EmptySpace max="-2" attributes="0"/> 38 | <Group type="103" groupAlignment="0" attributes="0"> 39 | <Component id="jPanel2" min="-2" max="-2" attributes="0"/> 40 | <Component id="jPanel1" min="-2" max="-2" attributes="0"/> 41 | </Group> 42 | <EmptySpace max="-2" attributes="0"/> 43 | <Component id="jPanel3" min="-2" pref="84" max="-2" attributes="0"/> 44 | <EmptySpace max="-2" attributes="0"/> 45 | <Component id="jPanel6" min="-2" max="-2" attributes="0"/> 46 | <EmptySpace max="32767" attributes="0"/> 47 | </Group> 48 | </Group> 49 | </DimensionLayout> 50 | </Layout> 51 | <SubComponents> 52 | <Container class="javax.swing.JPanel" name="jPanel1"> 53 | <Properties> 54 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 55 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 56 | <TitledBorder title="Web Server"/> 57 | </Border> 58 | </Property> 59 | </Properties> 60 | 61 | <Layout> 62 | <DimensionLayout dim="0"> 63 | <Group type="103" groupAlignment="0" attributes="0"> 64 | <Group type="102" alignment="0" attributes="0"> 65 | <EmptySpace min="-2" max="-2" attributes="0"/> 66 | <Component id="jLabel1" min="-2" max="-2" attributes="0"/> 67 | <EmptySpace max="-2" attributes="0"/> 68 | <Component id="serverAddressTextField" max="32767" attributes="0"/> 69 | <EmptySpace type="unrelated" max="-2" attributes="0"/> 70 | <Component id="jLabel2" min="-2" max="-2" attributes="0"/> 71 | <EmptySpace max="-2" attributes="0"/> 72 | <Component id="serverPortTextField" min="-2" pref="43" max="-2" attributes="0"/> 73 | <EmptySpace max="-2" attributes="0"/> 74 | </Group> 75 | </Group> 76 | </DimensionLayout> 77 | <DimensionLayout dim="1"> 78 | <Group type="103" groupAlignment="0" attributes="0"> 79 | <Group type="102" attributes="0"> 80 | <EmptySpace max="-2" attributes="0"/> 81 | <Group type="103" groupAlignment="3" attributes="0"> 82 | <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> 83 | <Component id="serverAddressTextField" alignment="3" min="-2" max="-2" attributes="0"/> 84 | <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> 85 | <Component id="serverPortTextField" alignment="3" min="-2" max="-2" attributes="0"/> 86 | </Group> 87 | <EmptySpace max="32767" attributes="0"/> 88 | </Group> 89 | </Group> 90 | </DimensionLayout> 91 | </Layout> 92 | <SubComponents> 93 | <Component class="javax.swing.JLabel" name="jLabel1"> 94 | <Properties> 95 | <Property name="text" type="java.lang.String" value="Server Name or IP:"/> 96 | </Properties> 97 | </Component> 98 | <Component class="javax.swing.JTextField" name="serverAddressTextField"> 99 | </Component> 100 | <Component class="javax.swing.JLabel" name="jLabel2"> 101 | <Properties> 102 | <Property name="text" type="java.lang.String" value="Port Number:"/> 103 | </Properties> 104 | </Component> 105 | <Component class="javax.swing.JTextField" name="serverPortTextField"> 106 | </Component> 107 | </SubComponents> 108 | </Container> 109 | <Container class="javax.swing.JPanel" name="jPanel2"> 110 | <Properties> 111 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 112 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 113 | <TitledBorder title="Timeout (milliseconds)"/> 114 | </Border> 115 | </Property> 116 | </Properties> 117 | 118 | <Layout> 119 | <DimensionLayout dim="0"> 120 | <Group type="103" groupAlignment="0" attributes="0"> 121 | <Group type="102" alignment="0" attributes="0"> 122 | <EmptySpace min="-2" max="-2" attributes="0"/> 123 | <Component id="jLabel3" min="-2" max="-2" attributes="0"/> 124 | <EmptySpace max="-2" attributes="0"/> 125 | <Component id="connectionTimeoutTextField" max="32767" attributes="0"/> 126 | <EmptySpace max="-2" attributes="0"/> 127 | </Group> 128 | </Group> 129 | </DimensionLayout> 130 | <DimensionLayout dim="1"> 131 | <Group type="103" groupAlignment="0" attributes="0"> 132 | <Group type="102" alignment="0" attributes="0"> 133 | <EmptySpace max="-2" attributes="0"/> 134 | <Group type="103" groupAlignment="3" attributes="0"> 135 | <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> 136 | <Component id="connectionTimeoutTextField" alignment="3" min="-2" max="-2" attributes="0"/> 137 | </Group> 138 | <EmptySpace max="32767" attributes="0"/> 139 | </Group> 140 | </Group> 141 | </DimensionLayout> 142 | </Layout> 143 | <SubComponents> 144 | <Component class="javax.swing.JLabel" name="jLabel3"> 145 | <Properties> 146 | <Property name="text" type="java.lang.String" value="Connection:"/> 147 | </Properties> 148 | </Component> 149 | <Component class="javax.swing.JTextField" name="connectionTimeoutTextField"> 150 | </Component> 151 | </SubComponents> 152 | </Container> 153 | <Container class="javax.swing.JPanel" name="jPanel3"> 154 | <Properties> 155 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 156 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 157 | <TitledBorder title="WebSocket Settings"/> 158 | </Border> 159 | </Property> 160 | </Properties> 161 | 162 | <Layout> 163 | <DimensionLayout dim="0"> 164 | <Group type="103" groupAlignment="0" attributes="0"> 165 | <Group type="102" attributes="0"> 166 | <EmptySpace max="-2" attributes="0"/> 167 | <Group type="103" groupAlignment="0" attributes="0"> 168 | <Group type="102" alignment="0" attributes="0"> 169 | <Component id="jLabel15" min="-2" max="-2" attributes="0"/> 170 | <EmptySpace max="-2" attributes="0"/> 171 | <Component id="implementationComboBox" max="32767" attributes="0"/> 172 | <EmptySpace type="separate" max="-2" attributes="0"/> 173 | <Component id="jLabel4" min="-2" max="-2" attributes="0"/> 174 | <EmptySpace min="-2" max="-2" attributes="0"/> 175 | <Component id="protocolTextField" min="-2" pref="40" max="-2" attributes="0"/> 176 | <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> 177 | <Component id="jLabel6" min="-2" max="-2" attributes="0"/> 178 | <EmptySpace min="-2" max="-2" attributes="0"/> 179 | <Component id="contentEncodingTextField" min="-2" pref="40" max="-2" attributes="0"/> 180 | </Group> 181 | <Group type="102" attributes="0"> 182 | <Component id="ignoreSslErrorsCheckBox" min="-2" max="-2" attributes="0"/> 183 | <EmptySpace min="0" pref="0" max="32767" attributes="0"/> 184 | </Group> 185 | </Group> 186 | <EmptySpace max="-2" attributes="0"/> 187 | </Group> 188 | </Group> 189 | </DimensionLayout> 190 | <DimensionLayout dim="1"> 191 | <Group type="103" groupAlignment="0" attributes="0"> 192 | <Group type="102" alignment="0" attributes="0"> 193 | <EmptySpace max="32767" attributes="0"/> 194 | <Group type="103" groupAlignment="3" attributes="0"> 195 | <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> 196 | <Component id="protocolTextField" alignment="3" min="-2" max="-2" attributes="0"/> 197 | <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> 198 | <Component id="contentEncodingTextField" alignment="3" min="-2" max="-2" attributes="0"/> 199 | <Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/> 200 | <Component id="implementationComboBox" alignment="3" min="-2" max="-2" attributes="0"/> 201 | </Group> 202 | <EmptySpace type="unrelated" max="-2" attributes="0"/> 203 | <Component id="ignoreSslErrorsCheckBox" min="-2" max="-2" attributes="0"/> 204 | </Group> 205 | </Group> 206 | </DimensionLayout> 207 | </Layout> 208 | <SubComponents> 209 | <Component class="javax.swing.JLabel" name="jLabel4"> 210 | <Properties> 211 | <Property name="text" type="java.lang.String" value="Protocol [ws/wss]:"/> 212 | </Properties> 213 | </Component> 214 | <Component class="javax.swing.JLabel" name="jLabel6"> 215 | <Properties> 216 | <Property name="text" type="java.lang.String" value="Content encoding:"/> 217 | </Properties> 218 | </Component> 219 | <Component class="javax.swing.JTextField" name="protocolTextField"> 220 | <Properties> 221 | <Property name="toolTipText" type="java.lang.String" value=""/> 222 | </Properties> 223 | </Component> 224 | <Component class="javax.swing.JTextField" name="contentEncodingTextField"> 225 | </Component> 226 | <Component class="javax.swing.JCheckBox" name="ignoreSslErrorsCheckBox"> 227 | <Properties> 228 | <Property name="text" type="java.lang.String" value="Ignore SSL certificate errors"/> 229 | </Properties> 230 | </Component> 231 | <Component class="javax.swing.JLabel" name="jLabel15"> 232 | <Properties> 233 | <Property name="text" type="java.lang.String" value="Implementation:"/> 234 | </Properties> 235 | </Component> 236 | <Component class="javax.swing.JComboBox" name="implementationComboBox"> 237 | <Properties> 238 | <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> 239 | <StringArray count="1"> 240 | <StringItem index="0" value="RFC6455 (v13)"/> 241 | </StringArray> 242 | </Property> 243 | </Properties> 244 | </Component> 245 | </SubComponents> 246 | </Container> 247 | <Container class="javax.swing.JPanel" name="jPanel6"> 248 | <Properties> 249 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 250 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 251 | <TitledBorder title="Proxy Server (currently not supported by Jetty)"/> 252 | </Border> 253 | </Property> 254 | </Properties> 255 | 256 | <Layout> 257 | <DimensionLayout dim="0"> 258 | <Group type="103" groupAlignment="0" attributes="0"> 259 | <Group type="102" attributes="0"> 260 | <EmptySpace max="-2" attributes="0"/> 261 | <Component id="jLabel10" min="-2" max="-2" attributes="0"/> 262 | <EmptySpace max="-2" attributes="0"/> 263 | <Component id="proxyAddressTextField" max="32767" attributes="0"/> 264 | <EmptySpace type="unrelated" max="-2" attributes="0"/> 265 | <Component id="jLabel11" min="-2" max="-2" attributes="0"/> 266 | <EmptySpace max="-2" attributes="0"/> 267 | <Component id="proxyPortTextField" min="-2" pref="39" max="-2" attributes="0"/> 268 | <EmptySpace type="separate" max="-2" attributes="0"/> 269 | <Component id="jLabel12" min="-2" max="-2" attributes="0"/> 270 | <EmptySpace max="-2" attributes="0"/> 271 | <Component id="proxyUsernameTextField" min="-2" pref="64" max="-2" attributes="0"/> 272 | <EmptySpace min="-2" pref="18" max="-2" attributes="0"/> 273 | <Component id="jLabel13" min="-2" max="-2" attributes="0"/> 274 | <EmptySpace max="-2" attributes="0"/> 275 | <Component id="proxyPasswordTextField" min="-2" pref="64" max="-2" attributes="0"/> 276 | <EmptySpace max="-2" attributes="0"/> 277 | </Group> 278 | </Group> 279 | </DimensionLayout> 280 | <DimensionLayout dim="1"> 281 | <Group type="103" groupAlignment="0" attributes="0"> 282 | <Group type="102" attributes="0"> 283 | <EmptySpace max="-2" attributes="0"/> 284 | <Group type="103" groupAlignment="0" attributes="0"> 285 | <Group type="103" alignment="0" groupAlignment="3" attributes="0"> 286 | <Component id="proxyUsernameTextField" alignment="3" min="-2" max="-2" attributes="0"/> 287 | <Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/> 288 | </Group> 289 | <Group type="103" groupAlignment="3" attributes="0"> 290 | <Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/> 291 | <Component id="proxyPortTextField" alignment="3" min="-2" max="-2" attributes="0"/> 292 | </Group> 293 | <Group type="103" groupAlignment="3" attributes="0"> 294 | <Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> 295 | <Component id="proxyAddressTextField" alignment="3" min="-2" max="-2" attributes="0"/> 296 | <Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> 297 | <Component id="proxyPasswordTextField" alignment="3" min="-2" max="-2" attributes="0"/> 298 | </Group> 299 | </Group> 300 | <EmptySpace max="32767" attributes="0"/> 301 | </Group> 302 | </Group> 303 | </DimensionLayout> 304 | </Layout> 305 | <SubComponents> 306 | <Component class="javax.swing.JLabel" name="jLabel10"> 307 | <Properties> 308 | <Property name="text" type="java.lang.String" value="Server Name or IP:"/> 309 | </Properties> 310 | </Component> 311 | <Component class="javax.swing.JTextField" name="proxyAddressTextField"> 312 | </Component> 313 | <Component class="javax.swing.JLabel" name="jLabel11"> 314 | <Properties> 315 | <Property name="text" type="java.lang.String" value="Port Number:"/> 316 | </Properties> 317 | </Component> 318 | <Component class="javax.swing.JTextField" name="proxyPortTextField"> 319 | </Component> 320 | <Component class="javax.swing.JLabel" name="jLabel12"> 321 | <Properties> 322 | <Property name="text" type="java.lang.String" value="Username:"/> 323 | </Properties> 324 | </Component> 325 | <Component class="javax.swing.JTextField" name="proxyUsernameTextField"> 326 | </Component> 327 | <Component class="javax.swing.JLabel" name="jLabel13"> 328 | <Properties> 329 | <Property name="text" type="java.lang.String" value="Password:"/> 330 | </Properties> 331 | </Component> 332 | <Component class="javax.swing.JTextField" name="proxyPasswordTextField"> 333 | </Component> 334 | </SubComponents> 335 | </Container> 336 | </SubComponents> 337 | </Form> 338 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/functional/samplers/websocket/WebSocketSampler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.samplers.websocket; 6 | 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.apache.jmeter.config.Argument; 9 | import org.apache.jmeter.config.Arguments; 10 | import org.apache.jmeter.protocol.http.control.Header; 11 | import org.apache.jmeter.protocol.http.control.HeaderManager; 12 | import org.apache.jmeter.protocol.http.util.EncoderCache; 13 | import org.apache.jmeter.protocol.http.util.HTTPArgument; 14 | import org.apache.jmeter.protocol.http.util.HTTPConstants; 15 | import org.apache.jmeter.samplers.AbstractSampler; 16 | import org.apache.jmeter.samplers.Entry; 17 | import org.apache.jmeter.samplers.SampleResult; 18 | import org.apache.jmeter.testelement.TestElement; 19 | import org.apache.jmeter.testelement.TestStateListener; 20 | import org.apache.jmeter.testelement.property.PropertyIterator; 21 | import org.apache.jmeter.testelement.property.StringProperty; 22 | import org.apache.jmeter.testelement.property.TestElementProperty; 23 | import org.apache.jorphan.logging.LoggingManager; 24 | import org.apache.jorphan.util.JOrphanUtils; 25 | import org.apache.log.Logger; 26 | import org.eclipse.jetty.util.ssl.SslContextFactory; 27 | import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; 28 | import org.eclipse.jetty.websocket.client.WebSocketClient; 29 | 30 | import java.io.IOException; 31 | import java.io.UnsupportedEncodingException; 32 | import java.net.URI; 33 | import java.net.URISyntaxException; 34 | import java.util.Map; 35 | import java.util.concurrent.ConcurrentHashMap; 36 | import java.util.concurrent.ExecutorService; 37 | import java.util.concurrent.Executors; 38 | import java.util.concurrent.TimeUnit; 39 | 40 | /** 41 | * 42 | * @author Maciej Zaleski 43 | */ 44 | public class WebSocketSampler extends AbstractSampler implements TestStateListener { 45 | public static int DEFAULT_CONNECTION_TIMEOUT = 20000; //20 sec 46 | public static int DEFAULT_RESPONSE_TIMEOUT = 20000; //20 sec 47 | public static int MESSAGE_BACKLOG_COUNT = 3; 48 | 49 | private static final Logger log = LoggingManager.getLoggerForClass(); 50 | 51 | private static final String ARG_VAL_SEP = "="; // $NON-NLS-1$ 52 | private static final String QRY_SEP = "&"; // $NON-NLS-1$ 53 | private static final String WS_PREFIX = "ws://"; // $NON-NLS-1$ 54 | private static final String WSS_PREFIX = "wss://"; // $NON-NLS-1$ 55 | private static final String DEFAULT_PROTOCOL = "ws"; 56 | 57 | private HeaderManager headerManager; 58 | 59 | private static Map<String, ServiceSocket> connectionList; 60 | 61 | private static ExecutorService executor = Executors.newCachedThreadPool(); 62 | 63 | public WebSocketSampler() { 64 | super(); 65 | setName("WebSocket sampler"); 66 | } 67 | 68 | private ServiceSocket getConnectionSocket() throws URISyntaxException, Exception { 69 | URI uri = getUri(); 70 | 71 | String connectionId = getThreadName() + getConnectionId(); 72 | 73 | // Get the existing socket for this client 74 | if (isStreamingConnection() && connectionList.containsKey(connectionId)) { 75 | ServiceSocket socket = connectionList.get(connectionId); 76 | socket.initialize(); 77 | 78 | // use new response and disconnect patterns if overriden 79 | if (this.isOverrideResponsePattern()) { 80 | socket.setResponsePattern(this.getResponsePattern()); 81 | } 82 | 83 | if (this.isOverrideDisconnectPattern()) { 84 | socket.setDisconnectPattern(this.getCloseConncectionPattern()); 85 | } 86 | 87 | return socket; 88 | } 89 | 90 | //Create WebSocket client 91 | SslContextFactory sslContexFactory = new SslContextFactory(); 92 | sslContexFactory.setTrustAll(isIgnoreSslErrors()); 93 | WebSocketClient webSocketClient = new WebSocketClient(sslContexFactory, executor); 94 | 95 | ServiceSocket socket = new ServiceSocket(this, webSocketClient); 96 | if (isStreamingConnection()) { 97 | connectionList.put(connectionId, socket); 98 | } 99 | 100 | //Start WebSocket client thread and upgrage HTTP connection 101 | webSocketClient.start(); 102 | ClientUpgradeRequest request = new ClientUpgradeRequest(); 103 | if (headerManager != null) { 104 | for (int i = 0; i < headerManager.size(); i++) { 105 | Header header = headerManager.get(i); 106 | request.setHeader(header.getName(), header.getValue()); 107 | } 108 | } 109 | 110 | webSocketClient.connect(socket, uri, request); 111 | 112 | //Get connection timeout or use the default value 113 | int connectionTimeout; 114 | try { 115 | connectionTimeout = Integer.parseInt(getConnectionTimeout()); 116 | } catch (NumberFormatException ex) { 117 | log.warn("Connection timeout is not a number; using the default connection timeout of " + DEFAULT_CONNECTION_TIMEOUT + "ms"); 118 | connectionTimeout = DEFAULT_CONNECTION_TIMEOUT; 119 | } 120 | 121 | socket.awaitOpen(connectionTimeout, TimeUnit.MILLISECONDS); 122 | 123 | return socket; 124 | } 125 | 126 | @Override 127 | public SampleResult sample(Entry entry) { 128 | ServiceSocket socket = null; 129 | SampleResult sampleResult = new SampleResult(); 130 | sampleResult.setSampleLabel(getName()); 131 | sampleResult.setDataEncoding(getContentEncoding()); 132 | 133 | //This StringBuilder will track all exceptions related to the protocol processing 134 | StringBuilder errorList = new StringBuilder(); 135 | errorList.append("\n\n[Problems]\n"); 136 | 137 | boolean isOK = false; 138 | 139 | //Set the message payload in the Sampler 140 | String payloadMessage = getRequestPayload(); 141 | sampleResult.setSamplerData(payloadMessage); 142 | 143 | //Could improve precission by moving this closer to the action 144 | sampleResult.sampleStart(); 145 | 146 | try { 147 | socket = getConnectionSocket(); 148 | if (socket == null) { 149 | //Couldn't open a connection, set the status and exit 150 | sampleResult.setResponseCode("500"); 151 | sampleResult.setSuccessful(false); 152 | sampleResult.sampleEnd(); 153 | sampleResult.setResponseMessage(errorList.toString()); 154 | errorList.append(" - Connection couldn't be opened").append("\n"); 155 | return sampleResult; 156 | } 157 | 158 | //Send message only if it is not empty 159 | if (!payloadMessage.isEmpty()) { 160 | socket.sendMessage(payloadMessage); 161 | } 162 | 163 | int responseTimeout; 164 | try { 165 | responseTimeout = Integer.parseInt(getResponseTimeout()); 166 | } catch (NumberFormatException ex) { 167 | log.warn("Request timeout is not a number; using the default request timeout of " + DEFAULT_RESPONSE_TIMEOUT + "ms"); 168 | responseTimeout = DEFAULT_RESPONSE_TIMEOUT; 169 | } 170 | 171 | //Wait for any of the following: 172 | // - Response matching response pattern is received 173 | // - Response matching connection closing pattern is received 174 | // - Timeout is reached 175 | socket.awaitClose(responseTimeout, TimeUnit.MILLISECONDS); 176 | 177 | //If no response is received set code 204; actually not used...needs to do something else 178 | if (socket.getResponseMessage() == null || socket.getResponseMessage().isEmpty()) { 179 | sampleResult.setResponseCode("204"); 180 | } 181 | 182 | //Set sampler response code 183 | if (socket.getError() != 0) { 184 | isOK = false; 185 | sampleResult.setResponseCode(socket.getError().toString()); 186 | } else { 187 | sampleResult.setResponseCodeOK(); 188 | isOK = true; 189 | } 190 | 191 | //set sampler response 192 | sampleResult.setResponseData(socket.getResponseMessage(), getContentEncoding()); 193 | 194 | } catch (URISyntaxException e) { 195 | errorList.append(" - Invalid URI syntax: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 196 | } catch (IOException e) { 197 | errorList.append(" - IO Exception: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 198 | } catch (NumberFormatException e) { 199 | errorList.append(" - Cannot parse number: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 200 | } catch (InterruptedException e) { 201 | errorList.append(" - Execution interrupted: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 202 | } catch (Exception e) { 203 | errorList.append(" - Unexpected error: ").append(e.getMessage()).append("\n").append(StringUtils.join(e.getStackTrace(), "\n")).append("\n"); 204 | } 205 | 206 | sampleResult.sampleEnd(); 207 | sampleResult.setSuccessful(isOK); 208 | 209 | String logMessage = (socket != null) ? socket.getLogMessage() : ""; 210 | sampleResult.setResponseMessage(logMessage + errorList); 211 | return sampleResult; 212 | } 213 | 214 | @Override 215 | public void setName(String name) { 216 | if (name != null) { 217 | setProperty(TestElement.NAME, name); 218 | } 219 | } 220 | 221 | @Override 222 | public String getName() { 223 | return getPropertyAsString(TestElement.NAME); 224 | } 225 | 226 | @Override 227 | public void setComment(String comment) { 228 | setProperty(new StringProperty(TestElement.COMMENTS, comment)); 229 | } 230 | 231 | @Override 232 | public String getComment() { 233 | return getProperty(TestElement.COMMENTS).getStringValue(); 234 | } 235 | 236 | public URI getUri() throws URISyntaxException { 237 | String path = this.getContextPath(); 238 | // Hack to allow entire URL to be provided in host field 239 | if (path.startsWith(WS_PREFIX) 240 | || path.startsWith(WSS_PREFIX)) { 241 | return new URI(path); 242 | } 243 | String domain = getServerAddress(); 244 | String protocol = getProtocol(); 245 | // HTTP URLs must be absolute, allow file to be relative 246 | if (!path.startsWith("/")) { // $NON-NLS-1$ 247 | path = "/" + path; // $NON-NLS-1$ 248 | } 249 | 250 | String queryString = getQueryString(getContentEncoding()); 251 | if (isProtocolDefaultPort()) { 252 | return new URI(protocol, null, domain, -1, path, queryString, null); 253 | } 254 | return new URI(protocol, null, domain, Integer.parseInt(getServerPort()), path, queryString, null); 255 | } 256 | 257 | /** 258 | * Tell whether the default port for the specified protocol is used 259 | * 260 | * @return true if the default port number for the protocol is used, false 261 | * otherwise 262 | */ 263 | public boolean isProtocolDefaultPort() { 264 | final int port = Integer.parseInt(getServerPort()); 265 | final String protocol = getProtocol(); 266 | return ("ws".equalsIgnoreCase(protocol) && port == HTTPConstants.DEFAULT_HTTP_PORT) 267 | || ("wss".equalsIgnoreCase(protocol) && port == HTTPConstants.DEFAULT_HTTPS_PORT); 268 | } 269 | 270 | public String getServerPort() { 271 | final String port_s = getPropertyAsString("serverPort", "0"); 272 | Integer port; 273 | String protocol = getProtocol(); 274 | 275 | try { 276 | port = Integer.parseInt(port_s); 277 | } catch (Exception ex) { 278 | port = 0; 279 | } 280 | 281 | if (port == 0) { 282 | if ("wss".equalsIgnoreCase(protocol)) { 283 | return String.valueOf(HTTPConstants.DEFAULT_HTTPS_PORT); 284 | } else if ("ws".equalsIgnoreCase(protocol)) { 285 | return String.valueOf(HTTPConstants.DEFAULT_HTTP_PORT); 286 | } 287 | } 288 | return port.toString(); 289 | } 290 | 291 | public void setServerPort(String port) { 292 | setProperty("serverPort", port); 293 | } 294 | 295 | public String getResponseTimeout() { 296 | return getPropertyAsString("responseTimeout", "20000"); 297 | } 298 | 299 | public void setResponseTimeout(String responseTimeout) { 300 | setProperty("responseTimeout", responseTimeout); 301 | } 302 | 303 | 304 | public String getConnectionTimeout() { 305 | return getPropertyAsString("connectionTimeout", "5000"); 306 | } 307 | 308 | public void setConnectionTimeout(String connectionTimeout) { 309 | setProperty("connectionTimeout", connectionTimeout); 310 | } 311 | 312 | public void setProtocol(String protocol) { 313 | setProperty("protocol", protocol); 314 | } 315 | 316 | public String getProtocol() { 317 | String protocol = getPropertyAsString("protocol"); 318 | if (protocol == null || protocol.isEmpty()) { 319 | return DEFAULT_PROTOCOL; 320 | } 321 | return protocol; 322 | } 323 | 324 | public void setServerAddress(String serverAddress) { 325 | setProperty("serverAddress", serverAddress); 326 | } 327 | 328 | public String getServerAddress() { 329 | return getPropertyAsString("serverAddress"); 330 | } 331 | 332 | 333 | public void setImplementation(String implementation) { 334 | setProperty("implementation", implementation); 335 | } 336 | 337 | public String getImplementation() { 338 | return getPropertyAsString("implementation"); 339 | } 340 | 341 | public void setContextPath(String contextPath) { 342 | setProperty("contextPath", contextPath); 343 | } 344 | 345 | public String getContextPath() { 346 | return getPropertyAsString("contextPath"); 347 | } 348 | 349 | public void setContentEncoding(String contentEncoding) { 350 | setProperty("contentEncoding", contentEncoding); 351 | } 352 | 353 | public String getContentEncoding() { 354 | return getPropertyAsString("contentEncoding", "UTF-8"); 355 | } 356 | 357 | public void setRequestPayload(String requestPayload) { 358 | setProperty("requestPayload", requestPayload); 359 | } 360 | 361 | public String getRequestPayload() { 362 | return getPropertyAsString("requestPayload"); 363 | } 364 | 365 | public void setIgnoreSslErrors(Boolean ignoreSslErrors) { 366 | setProperty("ignoreSslErrors", ignoreSslErrors); 367 | } 368 | 369 | public Boolean isIgnoreSslErrors() { 370 | return getPropertyAsBoolean("ignoreSslErrors"); 371 | } 372 | 373 | public void setStreamingConnection(Boolean streamingConnection) { 374 | setProperty("streamingConnection", streamingConnection); 375 | } 376 | 377 | public Boolean isStreamingConnection() { 378 | return getPropertyAsBoolean("streamingConnection"); 379 | } 380 | 381 | public void setConnectionId(String connectionId) { 382 | setProperty("connectionId", connectionId); 383 | } 384 | 385 | public String getConnectionId() { 386 | return getPropertyAsString("connectionId"); 387 | } 388 | 389 | public void setResponsePattern(String responsePattern) { 390 | setProperty("responsePattern", responsePattern); 391 | } 392 | 393 | public String getResponsePattern() { 394 | return getPropertyAsString("responsePattern"); 395 | } 396 | 397 | public void setCloseConncectionPattern(String closeConncectionPattern) { 398 | setProperty("closeConncectionPattern", closeConncectionPattern); 399 | } 400 | 401 | public String getCloseConncectionPattern() { 402 | return getPropertyAsString("closeConncectionPattern"); 403 | } 404 | 405 | void setOverrideResponsePattern(Boolean overrideResponsePattern) { 406 | setProperty("isOverrideResponsePattern", overrideResponsePattern); 407 | } 408 | 409 | Boolean isOverrideResponsePattern() { 410 | return getPropertyAsBoolean("isOverrideResponsePattern", false); 411 | } 412 | 413 | void setOverrideDisconnectPattern(Boolean overrideDisconnectPattern) { 414 | setProperty("isOverrideDisconnectPattern", overrideDisconnectPattern); 415 | } 416 | 417 | Boolean isOverrideDisconnectPattern() { 418 | return getPropertyAsBoolean("isOverrideDisconnectPattern", false); 419 | } 420 | 421 | public void setProxyAddress(String proxyAddress) { 422 | setProperty("proxyAddress", proxyAddress); 423 | } 424 | 425 | public String getProxyAddress() { 426 | return getPropertyAsString("proxyAddress"); 427 | } 428 | 429 | public void setProxyPassword(String proxyPassword) { 430 | setProperty("proxyPassword", proxyPassword); 431 | } 432 | 433 | public String getProxyPassword() { 434 | return getPropertyAsString("proxyPassword"); 435 | } 436 | 437 | public void setProxyPort(String proxyPort) { 438 | setProperty("proxyPort", proxyPort); 439 | } 440 | 441 | public String getProxyPort() { 442 | return getPropertyAsString("proxyPort"); 443 | } 444 | 445 | public void setProxyUsername(String proxyUsername) { 446 | setProperty("proxyUsername", proxyUsername); 447 | } 448 | 449 | public String getProxyUsername() { 450 | return getPropertyAsString("proxyUsername"); 451 | } 452 | 453 | public void setMessageBacklog(String messageBacklog) { 454 | setProperty("messageBacklog", messageBacklog); 455 | } 456 | 457 | public String getMessageBacklog() { 458 | return getPropertyAsString("messageBacklog", "3"); 459 | } 460 | 461 | 462 | 463 | public String getQueryString(String contentEncoding) { 464 | // Check if the sampler has a specified content encoding 465 | if (JOrphanUtils.isBlank(contentEncoding)) { 466 | // We use the encoding which should be used according to the HTTP spec, which is UTF-8 467 | contentEncoding = EncoderCache.URL_ARGUMENT_ENCODING; 468 | } 469 | StringBuilder buf = new StringBuilder(); 470 | PropertyIterator iter = getQueryStringParameters().iterator(); 471 | boolean first = true; 472 | while (iter.hasNext()) { 473 | HTTPArgument item = null; 474 | Object objectValue = iter.next().getObjectValue(); 475 | try { 476 | item = (HTTPArgument) objectValue; 477 | } catch (ClassCastException e) { 478 | item = new HTTPArgument((Argument) objectValue); 479 | } 480 | final String encodedName = item.getEncodedName(); 481 | if (encodedName.length() == 0) { 482 | continue; // Skip parameters with a blank name (allows use of optional variables in parameter lists) 483 | } 484 | if (!first) { 485 | buf.append(QRY_SEP); 486 | } else { 487 | first = false; 488 | } 489 | buf.append(encodedName); 490 | if (item.getMetaData() == null) { 491 | buf.append(ARG_VAL_SEP); 492 | } else { 493 | buf.append(item.getMetaData()); 494 | } 495 | 496 | // Encode the parameter value in the specified content encoding 497 | try { 498 | buf.append(item.getEncodedValue(contentEncoding)); 499 | } catch (UnsupportedEncodingException e) { 500 | log.warn("Unable to encode parameter in encoding " + contentEncoding + ", parameter value not included in query string"); 501 | } 502 | } 503 | return buf.toString(); 504 | } 505 | 506 | public void setQueryStringParameters(Arguments queryStringParameters) { 507 | setProperty(new TestElementProperty("queryStringParameters", queryStringParameters)); 508 | } 509 | 510 | public Arguments getQueryStringParameters() { 511 | Arguments args = (Arguments) getProperty("queryStringParameters").getObjectValue(); 512 | return args; 513 | } 514 | 515 | public void addTestElement(TestElement el) { 516 | if (el instanceof HeaderManager) { 517 | headerManager = (HeaderManager) el; 518 | } else { 519 | super.addTestElement(el); 520 | } 521 | } 522 | 523 | @Override 524 | public void testStarted() { 525 | testStarted("unknown"); 526 | } 527 | 528 | @Override 529 | public void testStarted(String host) { 530 | connectionList = new ConcurrentHashMap<String, ServiceSocket>(); 531 | } 532 | 533 | @Override 534 | public void testEnded() { 535 | testEnded("unknown"); 536 | } 537 | 538 | @Override 539 | public void testEnded(String host) { 540 | for (ServiceSocket socket : connectionList.values()) { 541 | socket.close(); 542 | } 543 | } 544 | 545 | } 546 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/controler/websocketapp/WebSocketApplicationConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.controler.websocketapp; 6 | 7 | import JMeter.plugins.functional.samplers.websocket.*; 8 | import java.awt.Color; 9 | import org.apache.jmeter.config.gui.ArgumentsPanel; 10 | import org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel; 11 | import org.apache.jorphan.logging.LoggingManager; 12 | import org.apache.log.Logger; 13 | 14 | /** 15 | * 16 | * @author Maciej Zaleski 17 | */ 18 | public class WebSocketApplicationConfig extends javax.swing.JPanel { 19 | private static final Logger log = LoggingManager.getLoggerForClass(); 20 | private HTTPArgumentsPanel attributePanel; 21 | 22 | /** 23 | * Creates new form WebSocketSamplerPanel 24 | */ 25 | public WebSocketApplicationConfig() { 26 | initComponents(); 27 | 28 | attributePanel = new HTTPArgumentsPanel(); 29 | querystringAttributesPanel.add(attributePanel); 30 | } 31 | 32 | /** 33 | * This method is called from within the constructor to initialize the form. 34 | * WARNING: Do NOT modify this code. The content of this method is always 35 | * regenerated by the Form Editor. 36 | */ 37 | @SuppressWarnings("unchecked") 38 | // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents 39 | private void initComponents() { 40 | 41 | jPanel1 = new javax.swing.JPanel(); 42 | jLabel1 = new javax.swing.JLabel(); 43 | serverAddressTextField = new javax.swing.JTextField(); 44 | jLabel2 = new javax.swing.JLabel(); 45 | serverPortTextField = new javax.swing.JTextField(); 46 | jPanel2 = new javax.swing.JPanel(); 47 | jLabel3 = new javax.swing.JLabel(); 48 | connectionTimeoutTextField = new javax.swing.JTextField(); 49 | jPanel3 = new javax.swing.JPanel(); 50 | jLabel4 = new javax.swing.JLabel(); 51 | jLabel6 = new javax.swing.JLabel(); 52 | protocolTextField = new javax.swing.JTextField(); 53 | contentEncodingTextField = new javax.swing.JTextField(); 54 | ignoreSslErrorsCheckBox = new javax.swing.JCheckBox(); 55 | jLabel15 = new javax.swing.JLabel(); 56 | implementationComboBox = new javax.swing.JComboBox(); 57 | jPanel6 = new javax.swing.JPanel(); 58 | jLabel10 = new javax.swing.JLabel(); 59 | proxyAddressTextField = new javax.swing.JTextField(); 60 | jLabel11 = new javax.swing.JLabel(); 61 | proxyPortTextField = new javax.swing.JTextField(); 62 | jLabel12 = new javax.swing.JLabel(); 63 | proxyUsernameTextField = new javax.swing.JTextField(); 64 | jLabel13 = new javax.swing.JLabel(); 65 | proxyPasswordTextField = new javax.swing.JTextField(); 66 | 67 | jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Web Server")); 68 | 69 | jLabel1.setText("Server Name or IP:"); 70 | 71 | jLabel2.setText("Port Number:"); 72 | 73 | javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 74 | jPanel1.setLayout(jPanel1Layout); 75 | jPanel1Layout.setHorizontalGroup( 76 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 77 | .addGroup(jPanel1Layout.createSequentialGroup() 78 | .addContainerGap() 79 | .addComponent(jLabel1) 80 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 81 | .addComponent(serverAddressTextField) 82 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 83 | .addComponent(jLabel2) 84 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 85 | .addComponent(serverPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE) 86 | .addContainerGap()) 87 | ); 88 | jPanel1Layout.setVerticalGroup( 89 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 90 | .addGroup(jPanel1Layout.createSequentialGroup() 91 | .addContainerGap() 92 | .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 93 | .addComponent(jLabel1) 94 | .addComponent(serverAddressTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 95 | .addComponent(jLabel2) 96 | .addComponent(serverPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 97 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 98 | ); 99 | 100 | jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Timeout (milliseconds)")); 101 | 102 | jLabel3.setText("Connection:"); 103 | 104 | javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); 105 | jPanel2.setLayout(jPanel2Layout); 106 | jPanel2Layout.setHorizontalGroup( 107 | jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 108 | .addGroup(jPanel2Layout.createSequentialGroup() 109 | .addContainerGap() 110 | .addComponent(jLabel3) 111 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 112 | .addComponent(connectionTimeoutTextField) 113 | .addContainerGap()) 114 | ); 115 | jPanel2Layout.setVerticalGroup( 116 | jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 117 | .addGroup(jPanel2Layout.createSequentialGroup() 118 | .addContainerGap() 119 | .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 120 | .addComponent(jLabel3) 121 | .addComponent(connectionTimeoutTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 122 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 123 | ); 124 | 125 | jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("WebSocket Settings")); 126 | 127 | jLabel4.setText("Protocol [ws/wss]:"); 128 | 129 | jLabel6.setText("Content encoding:"); 130 | 131 | protocolTextField.setToolTipText(""); 132 | 133 | ignoreSslErrorsCheckBox.setText("Ignore SSL certificate errors"); 134 | 135 | jLabel15.setText("Implementation:"); 136 | 137 | implementationComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "RFC6455 (v13)" })); 138 | 139 | javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); 140 | jPanel3.setLayout(jPanel3Layout); 141 | jPanel3Layout.setHorizontalGroup( 142 | jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 143 | .addGroup(jPanel3Layout.createSequentialGroup() 144 | .addContainerGap() 145 | .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 146 | .addGroup(jPanel3Layout.createSequentialGroup() 147 | .addComponent(jLabel15) 148 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 149 | .addComponent(implementationComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 150 | .addGap(18, 18, 18) 151 | .addComponent(jLabel4) 152 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 153 | .addComponent(protocolTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) 154 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 155 | .addComponent(jLabel6) 156 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 157 | .addComponent(contentEncodingTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)) 158 | .addGroup(jPanel3Layout.createSequentialGroup() 159 | .addComponent(ignoreSslErrorsCheckBox) 160 | .addGap(0, 0, Short.MAX_VALUE))) 161 | .addContainerGap()) 162 | ); 163 | jPanel3Layout.setVerticalGroup( 164 | jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 165 | .addGroup(jPanel3Layout.createSequentialGroup() 166 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 167 | .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 168 | .addComponent(jLabel4) 169 | .addComponent(protocolTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 170 | .addComponent(jLabel6) 171 | .addComponent(contentEncodingTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 172 | .addComponent(jLabel15) 173 | .addComponent(implementationComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 174 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 175 | .addComponent(ignoreSslErrorsCheckBox)) 176 | ); 177 | 178 | jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder("Proxy Server (currently not supported by Jetty)")); 179 | 180 | jLabel10.setText("Server Name or IP:"); 181 | 182 | jLabel11.setText("Port Number:"); 183 | 184 | jLabel12.setText("Username:"); 185 | 186 | jLabel13.setText("Password:"); 187 | 188 | javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); 189 | jPanel6.setLayout(jPanel6Layout); 190 | jPanel6Layout.setHorizontalGroup( 191 | jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 192 | .addGroup(jPanel6Layout.createSequentialGroup() 193 | .addContainerGap() 194 | .addComponent(jLabel10) 195 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 196 | .addComponent(proxyAddressTextField) 197 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 198 | .addComponent(jLabel11) 199 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 200 | .addComponent(proxyPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE) 201 | .addGap(18, 18, 18) 202 | .addComponent(jLabel12) 203 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 204 | .addComponent(proxyUsernameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) 205 | .addGap(18, 18, 18) 206 | .addComponent(jLabel13) 207 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 208 | .addComponent(proxyPasswordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) 209 | .addContainerGap()) 210 | ); 211 | jPanel6Layout.setVerticalGroup( 212 | jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 213 | .addGroup(jPanel6Layout.createSequentialGroup() 214 | .addContainerGap() 215 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 216 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 217 | .addComponent(proxyUsernameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 218 | .addComponent(jLabel12)) 219 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 220 | .addComponent(jLabel11) 221 | .addComponent(proxyPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 222 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 223 | .addComponent(jLabel10) 224 | .addComponent(proxyAddressTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 225 | .addComponent(jLabel13) 226 | .addComponent(proxyPasswordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) 227 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 228 | ); 229 | 230 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 231 | this.setLayout(layout); 232 | layout.setHorizontalGroup( 233 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 234 | .addGroup(layout.createSequentialGroup() 235 | .addContainerGap() 236 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 237 | .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 238 | .addGroup(layout.createSequentialGroup() 239 | .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 240 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 241 | .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 242 | .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 243 | .addContainerGap()) 244 | ); 245 | layout.setVerticalGroup( 246 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 247 | .addGroup(layout.createSequentialGroup() 248 | .addContainerGap() 249 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 250 | .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 251 | .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 252 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 253 | .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) 254 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 255 | .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 256 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 257 | ); 258 | }// </editor-fold>//GEN-END:initComponents 259 | // Variables declaration - do not modify//GEN-BEGIN:variables 260 | private javax.swing.JTextField connectionTimeoutTextField; 261 | private javax.swing.JTextField contentEncodingTextField; 262 | private javax.swing.JCheckBox ignoreSslErrorsCheckBox; 263 | private javax.swing.JComboBox implementationComboBox; 264 | private javax.swing.JLabel jLabel1; 265 | private javax.swing.JLabel jLabel10; 266 | private javax.swing.JLabel jLabel11; 267 | private javax.swing.JLabel jLabel12; 268 | private javax.swing.JLabel jLabel13; 269 | private javax.swing.JLabel jLabel15; 270 | private javax.swing.JLabel jLabel2; 271 | private javax.swing.JLabel jLabel3; 272 | private javax.swing.JLabel jLabel4; 273 | private javax.swing.JLabel jLabel6; 274 | private javax.swing.JPanel jPanel1; 275 | private javax.swing.JPanel jPanel2; 276 | private javax.swing.JPanel jPanel3; 277 | private javax.swing.JPanel jPanel6; 278 | private javax.swing.JTextField protocolTextField; 279 | private javax.swing.JTextField proxyAddressTextField; 280 | private javax.swing.JTextField proxyPasswordTextField; 281 | private javax.swing.JTextField proxyPortTextField; 282 | private javax.swing.JTextField proxyUsernameTextField; 283 | private javax.swing.JTextField serverAddressTextField; 284 | private javax.swing.JTextField serverPortTextField; 285 | // End of variables declaration//GEN-END:variables 286 | 287 | public void initFields() { 288 | } 289 | 290 | public void setCloseConncectionPattern(String closeConncectionPattern) { 291 | closeConncectionPatternTextField.setText(closeConncectionPattern); 292 | } 293 | 294 | public String getCloseConncectionPattern() { 295 | return closeConncectionPatternTextField.getText(); 296 | } 297 | 298 | public void setConnectionId(String connectionId) { 299 | connectionIdTextField.setText(connectionId); 300 | } 301 | 302 | public String getConnectionId() { 303 | return connectionIdTextField.getText(); 304 | } 305 | 306 | public void setContentEncoding(String contentEncoding) { 307 | contentEncodingTextField.setText(contentEncoding); 308 | } 309 | 310 | public String getContentEncoding() { 311 | return contentEncodingTextField.getText(); 312 | } 313 | 314 | public void setContextPath(String contextPath) { 315 | contextPathTextField.setText(contextPath); 316 | } 317 | 318 | public String getContextPath() { 319 | return contextPathTextField.getText(); 320 | } 321 | 322 | public void setProtocol(String protocol) { 323 | protocolTextField.setText(protocol); 324 | } 325 | 326 | public String getProtocol() { 327 | return protocolTextField.getText(); 328 | } 329 | 330 | public void setProxyAddress(String proxyAddress) { 331 | proxyAddressTextField.setText(proxyAddress); 332 | } 333 | 334 | public String getProxyAddress() { 335 | return proxyAddressTextField.getText(); 336 | } 337 | 338 | public void setProxyPassword(String proxyPassword) { 339 | proxyPasswordTextField.setText(proxyPassword); 340 | } 341 | 342 | public String getProxyPassword() { 343 | return proxyPasswordTextField.getText(); 344 | } 345 | 346 | public void setProxyPort(String proxyPort) { 347 | proxyPortTextField.setText(proxyPort); 348 | } 349 | 350 | public String getProxyPort() { 351 | return proxyPortTextField.getText(); 352 | } 353 | 354 | public void setProxyUsername(String proxyUsername) { 355 | proxyUsernameTextField.setText(proxyUsername); 356 | } 357 | 358 | public String getProxyUsername() { 359 | return proxyUsernameTextField.getText(); 360 | } 361 | 362 | public void setResponsePattern(String responsePattern) { 363 | responsePatternTextField.setText(responsePattern); 364 | } 365 | 366 | public String getResponsePattern() { 367 | return responsePatternTextField.getText(); 368 | } 369 | 370 | public void setResponseTimeout(String responseTimeout) { 371 | responseTimeoutTextField.setText(responseTimeout); 372 | } 373 | 374 | public String getResponseTimeout() { 375 | return responseTimeoutTextField.getText(); 376 | } 377 | 378 | public void setConnectionTimeout(String connectionTimeout) { 379 | connectionTimeoutTextField.setText(connectionTimeout); 380 | } 381 | 382 | public String getConnectionTimeout() { 383 | return connectionTimeoutTextField.getText(); 384 | } 385 | 386 | public void setServerAddress(String serverAddress) { 387 | serverAddressTextField.setText(serverAddress); 388 | } 389 | 390 | public String getServerAddress() { 391 | return serverAddressTextField.getText(); 392 | } 393 | 394 | public void setServerPort(String serverPort) { 395 | serverPortTextField.setText(serverPort); 396 | } 397 | 398 | public String getServerPort() { 399 | return serverPortTextField.getText(); 400 | } 401 | 402 | public void setRequestPayload(String requestPayload) { 403 | requestPayloadEditorPane.setText(requestPayload); 404 | } 405 | 406 | public String getRequestPayload() { 407 | return requestPayloadEditorPane.getText(); 408 | } 409 | 410 | public void setStreamingConnection(Boolean streamingConnection) { 411 | streamingConnectionCheckBox.setSelected(streamingConnection); 412 | } 413 | 414 | public Boolean isStreamingConnection() { 415 | return streamingConnectionCheckBox.isSelected(); 416 | } 417 | 418 | public void setIgnoreSslErrors(Boolean ignoreSslErrors) { 419 | ignoreSslErrorsCheckBox.setSelected(ignoreSslErrors); 420 | } 421 | 422 | public Boolean isIgnoreSslErrors() { 423 | return ignoreSslErrorsCheckBox.isSelected(); 424 | } 425 | 426 | public void setImplementation(String implementation) { 427 | implementationComboBox.setSelectedItem(implementation); 428 | } 429 | 430 | public String getImplementation() { 431 | return (String) implementationComboBox.getSelectedItem(); 432 | } 433 | 434 | public void setMessageBacklog(String messageBacklog) { 435 | messageBacklogTextField.setText(messageBacklog); 436 | } 437 | 438 | public String getMessageBacklog() { 439 | return messageBacklogTextField.getText(); 440 | } 441 | 442 | /** 443 | * @return the attributePanel 444 | */ 445 | public ArgumentsPanel getAttributePanel() { 446 | return attributePanel; 447 | } 448 | } 449 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/functional/samplers/websocket/WebSocketSamplerPanel.form: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" ?> 2 | 3 | <Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> 4 | <AuxValues> 5 | <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> 6 | <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> 7 | <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> 8 | <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> 9 | <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> 10 | <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> 11 | <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> 12 | <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> 13 | <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> 14 | </AuxValues> 15 | 16 | <Layout> 17 | <DimensionLayout dim="0"> 18 | <Group type="103" groupAlignment="0" attributes="0"> 19 | <Group type="102" attributes="0"> 20 | <EmptySpace min="-2" max="-2" attributes="0"/> 21 | <Group type="103" groupAlignment="0" attributes="0"> 22 | <Component id="jPanel3" max="32767" attributes="0"/> 23 | <Component id="jPanel5" max="32767" attributes="0"/> 24 | <Group type="102" alignment="0" attributes="0"> 25 | <Component id="jPanel1" max="32767" attributes="0"/> 26 | <EmptySpace min="-2" max="-2" attributes="0"/> 27 | <Component id="jPanel2" max="32767" attributes="0"/> 28 | </Group> 29 | <Component id="jPanel6" max="32767" attributes="0"/> 30 | </Group> 31 | <EmptySpace min="-2" max="-2" attributes="0"/> 32 | </Group> 33 | </Group> 34 | </DimensionLayout> 35 | <DimensionLayout dim="1"> 36 | <Group type="103" groupAlignment="0" attributes="0"> 37 | <Group type="102" alignment="0" attributes="0"> 38 | <EmptySpace max="-2" attributes="0"/> 39 | <Group type="103" groupAlignment="0" attributes="0"> 40 | <Component id="jPanel2" min="-2" max="-2" attributes="0"/> 41 | <Component id="jPanel1" min="-2" max="-2" attributes="0"/> 42 | </Group> 43 | <EmptySpace max="-2" attributes="0"/> 44 | <Component id="jPanel3" max="32767" attributes="0"/> 45 | <EmptySpace max="-2" attributes="0"/> 46 | <Component id="jPanel5" min="-2" max="-2" attributes="0"/> 47 | <EmptySpace max="-2" attributes="0"/> 48 | <Component id="jPanel6" min="-2" max="-2" attributes="0"/> 49 | <EmptySpace max="-2" attributes="0"/> 50 | </Group> 51 | </Group> 52 | </DimensionLayout> 53 | </Layout> 54 | <SubComponents> 55 | <Container class="javax.swing.JPanel" name="jPanel1"> 56 | <Properties> 57 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 58 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 59 | <TitledBorder title="Web Server"/> 60 | </Border> 61 | </Property> 62 | </Properties> 63 | 64 | <Layout> 65 | <DimensionLayout dim="0"> 66 | <Group type="103" groupAlignment="0" attributes="0"> 67 | <Group type="102" alignment="0" attributes="0"> 68 | <EmptySpace min="-2" max="-2" attributes="0"/> 69 | <Component id="jLabel1" min="-2" max="-2" attributes="0"/> 70 | <EmptySpace max="-2" attributes="0"/> 71 | <Component id="serverAddressTextField" max="32767" attributes="0"/> 72 | <EmptySpace type="unrelated" max="-2" attributes="0"/> 73 | <Component id="jLabel2" min="-2" max="-2" attributes="0"/> 74 | <EmptySpace max="-2" attributes="0"/> 75 | <Component id="serverPortTextField" min="-2" pref="43" max="-2" attributes="0"/> 76 | <EmptySpace max="-2" attributes="0"/> 77 | </Group> 78 | </Group> 79 | </DimensionLayout> 80 | <DimensionLayout dim="1"> 81 | <Group type="103" groupAlignment="0" attributes="0"> 82 | <Group type="102" attributes="0"> 83 | <EmptySpace max="-2" attributes="0"/> 84 | <Group type="103" groupAlignment="3" attributes="0"> 85 | <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> 86 | <Component id="serverAddressTextField" alignment="3" min="-2" max="-2" attributes="0"/> 87 | <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> 88 | <Component id="serverPortTextField" alignment="3" min="-2" max="-2" attributes="0"/> 89 | </Group> 90 | <EmptySpace max="32767" attributes="0"/> 91 | </Group> 92 | </Group> 93 | </DimensionLayout> 94 | </Layout> 95 | <SubComponents> 96 | <Component class="javax.swing.JLabel" name="jLabel1"> 97 | <Properties> 98 | <Property name="text" type="java.lang.String" value="Server Name or IP:"/> 99 | </Properties> 100 | </Component> 101 | <Component class="javax.swing.JTextField" name="serverAddressTextField"> 102 | </Component> 103 | <Component class="javax.swing.JLabel" name="jLabel2"> 104 | <Properties> 105 | <Property name="text" type="java.lang.String" value="Port Number:"/> 106 | </Properties> 107 | </Component> 108 | <Component class="javax.swing.JTextField" name="serverPortTextField"> 109 | </Component> 110 | </SubComponents> 111 | </Container> 112 | <Container class="javax.swing.JPanel" name="jPanel2"> 113 | <Properties> 114 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 115 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 116 | <TitledBorder title="Timeout (milliseconds)"/> 117 | </Border> 118 | </Property> 119 | </Properties> 120 | 121 | <Layout> 122 | <DimensionLayout dim="0"> 123 | <Group type="103" groupAlignment="0" attributes="0"> 124 | <Group type="102" alignment="0" attributes="0"> 125 | <EmptySpace min="-2" max="-2" attributes="0"/> 126 | <Component id="jLabel3" min="-2" max="-2" attributes="0"/> 127 | <EmptySpace min="-2" max="-2" attributes="0"/> 128 | <Component id="connectionTimeoutTextField" max="32767" attributes="0"/> 129 | <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> 130 | <Component id="jLabel17" min="-2" max="-2" attributes="0"/> 131 | <EmptySpace min="-2" max="-2" attributes="0"/> 132 | <Component id="responseTimeoutTextField" max="32767" attributes="0"/> 133 | <EmptySpace min="-2" max="-2" attributes="0"/> 134 | </Group> 135 | </Group> 136 | </DimensionLayout> 137 | <DimensionLayout dim="1"> 138 | <Group type="103" groupAlignment="0" attributes="0"> 139 | <Group type="102" alignment="0" attributes="0"> 140 | <EmptySpace max="-2" attributes="0"/> 141 | <Group type="103" groupAlignment="3" attributes="0"> 142 | <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> 143 | <Component id="connectionTimeoutTextField" alignment="3" min="-2" max="-2" attributes="0"/> 144 | <Component id="jLabel17" alignment="3" min="-2" max="-2" attributes="0"/> 145 | <Component id="responseTimeoutTextField" alignment="3" min="-2" max="-2" attributes="0"/> 146 | </Group> 147 | <EmptySpace max="32767" attributes="0"/> 148 | </Group> 149 | </Group> 150 | </DimensionLayout> 151 | </Layout> 152 | <SubComponents> 153 | <Component class="javax.swing.JLabel" name="jLabel3"> 154 | <Properties> 155 | <Property name="text" type="java.lang.String" value="Connection:"/> 156 | </Properties> 157 | </Component> 158 | <Component class="javax.swing.JTextField" name="connectionTimeoutTextField"> 159 | </Component> 160 | <Component class="javax.swing.JLabel" name="jLabel17"> 161 | <Properties> 162 | <Property name="text" type="java.lang.String" value="Response:"/> 163 | </Properties> 164 | </Component> 165 | <Component class="javax.swing.JTextField" name="responseTimeoutTextField"> 166 | </Component> 167 | </SubComponents> 168 | </Container> 169 | <Container class="javax.swing.JPanel" name="jPanel3"> 170 | <Properties> 171 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 172 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 173 | <TitledBorder title="WebSocket Request"/> 174 | </Border> 175 | </Property> 176 | </Properties> 177 | 178 | <Layout> 179 | <DimensionLayout dim="0"> 180 | <Group type="103" groupAlignment="0" attributes="0"> 181 | <Group type="102" attributes="0"> 182 | <EmptySpace min="-2" max="-2" attributes="0"/> 183 | <Group type="103" groupAlignment="0" attributes="0"> 184 | <Component id="querystringAttributesPanel" max="32767" attributes="0"/> 185 | <Component id="jScrollPane1" max="32767" attributes="0"/> 186 | <Group type="102" alignment="0" attributes="0"> 187 | <Component id="jLabel15" min="-2" max="-2" attributes="0"/> 188 | <EmptySpace min="-2" max="-2" attributes="0"/> 189 | <Component id="implementationComboBox" pref="0" max="32767" attributes="0"/> 190 | <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> 191 | <Component id="jLabel4" min="-2" max="-2" attributes="0"/> 192 | <EmptySpace min="-2" max="-2" attributes="0"/> 193 | <Component id="protocolTextField" min="-2" pref="40" max="-2" attributes="0"/> 194 | <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> 195 | <Component id="jLabel6" min="-2" max="-2" attributes="0"/> 196 | <EmptySpace min="-2" max="-2" attributes="0"/> 197 | <Component id="contentEncodingTextField" min="-2" pref="40" max="-2" attributes="0"/> 198 | <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> 199 | <Component id="jLabel8" min="-2" max="-2" attributes="0"/> 200 | <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> 201 | <Component id="connectionIdTextField" max="32767" attributes="0"/> 202 | </Group> 203 | <Group type="102" attributes="0"> 204 | <Group type="103" groupAlignment="0" attributes="0"> 205 | <Component id="jLabel14" min="-2" max="-2" attributes="0"/> 206 | <Group type="102" alignment="0" attributes="0"> 207 | <Component id="ignoreSslErrorsCheckBox" min="-2" max="-2" attributes="0"/> 208 | <EmptySpace type="unrelated" max="-2" attributes="0"/> 209 | <Component id="streamingConnectionCheckBox" min="-2" max="-2" attributes="0"/> 210 | </Group> 211 | </Group> 212 | <EmptySpace min="0" pref="0" max="32767" attributes="0"/> 213 | </Group> 214 | <Group type="102" alignment="0" attributes="0"> 215 | <Component id="jLabel5" min="-2" max="-2" attributes="0"/> 216 | <EmptySpace max="-2" attributes="0"/> 217 | <Component id="contextPathTextField" max="32767" attributes="0"/> 218 | </Group> 219 | </Group> 220 | <EmptySpace min="-2" max="-2" attributes="0"/> 221 | </Group> 222 | </Group> 223 | </DimensionLayout> 224 | <DimensionLayout dim="1"> 225 | <Group type="103" groupAlignment="0" attributes="0"> 226 | <Group type="102" alignment="0" attributes="0"> 227 | <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> 228 | <Group type="103" groupAlignment="3" attributes="0"> 229 | <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> 230 | <Component id="protocolTextField" alignment="3" min="-2" max="-2" attributes="0"/> 231 | <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> 232 | <Component id="contentEncodingTextField" alignment="3" min="-2" max="-2" attributes="0"/> 233 | <Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> 234 | <Component id="connectionIdTextField" alignment="3" min="-2" max="-2" attributes="0"/> 235 | <Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/> 236 | <Component id="implementationComboBox" alignment="3" min="-2" max="-2" attributes="0"/> 237 | </Group> 238 | <EmptySpace min="-2" max="-2" attributes="0"/> 239 | <Group type="103" groupAlignment="3" attributes="0"> 240 | <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> 241 | <Component id="contextPathTextField" alignment="3" min="-2" max="-2" attributes="0"/> 242 | </Group> 243 | <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> 244 | <Group type="103" groupAlignment="3" attributes="0"> 245 | <Component id="ignoreSslErrorsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/> 246 | <Component id="streamingConnectionCheckBox" alignment="3" min="-2" max="-2" attributes="0"/> 247 | </Group> 248 | <EmptySpace min="-2" max="-2" attributes="0"/> 249 | <Component id="querystringAttributesPanel" pref="102" max="32767" attributes="0"/> 250 | <EmptySpace min="-2" pref="8" max="-2" attributes="0"/> 251 | <Component id="jLabel14" min="-2" max="-2" attributes="0"/> 252 | <EmptySpace min="-2" max="-2" attributes="0"/> 253 | <Component id="jScrollPane1" pref="118" max="32767" attributes="0"/> 254 | <EmptySpace min="-2" max="-2" attributes="0"/> 255 | </Group> 256 | </Group> 257 | </DimensionLayout> 258 | </Layout> 259 | <SubComponents> 260 | <Component class="javax.swing.JLabel" name="jLabel4"> 261 | <Properties> 262 | <Property name="text" type="java.lang.String" value="Protocol [ws/wss]:"/> 263 | </Properties> 264 | </Component> 265 | <Component class="javax.swing.JLabel" name="jLabel5"> 266 | <Properties> 267 | <Property name="text" type="java.lang.String" value="Path:"/> 268 | </Properties> 269 | </Component> 270 | <Component class="javax.swing.JLabel" name="jLabel6"> 271 | <Properties> 272 | <Property name="text" type="java.lang.String" value="Content encoding:"/> 273 | </Properties> 274 | </Component> 275 | <Component class="javax.swing.JTextField" name="contextPathTextField"> 276 | </Component> 277 | <Component class="javax.swing.JTextField" name="protocolTextField"> 278 | <Properties> 279 | <Property name="toolTipText" type="java.lang.String" value=""/> 280 | </Properties> 281 | </Component> 282 | <Component class="javax.swing.JTextField" name="contentEncodingTextField"> 283 | </Component> 284 | <Component class="javax.swing.JLabel" name="jLabel8"> 285 | <Properties> 286 | <Property name="text" type="java.lang.String" value="Connection Id:"/> 287 | </Properties> 288 | </Component> 289 | <Component class="javax.swing.JTextField" name="connectionIdTextField"> 290 | </Component> 291 | <Container class="javax.swing.JPanel" name="querystringAttributesPanel"> 292 | 293 | <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/> 294 | </Container> 295 | <Component class="javax.swing.JCheckBox" name="ignoreSslErrorsCheckBox"> 296 | <Properties> 297 | <Property name="text" type="java.lang.String" value="Ignore SSL certificate errors"/> 298 | </Properties> 299 | </Component> 300 | <Container class="javax.swing.JScrollPane" name="jScrollPane1"> 301 | <AuxValues> 302 | <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> 303 | </AuxValues> 304 | 305 | <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> 306 | <SubComponents> 307 | <Component class="javax.swing.JEditorPane" name="requestPayloadEditorPane"> 308 | </Component> 309 | </SubComponents> 310 | </Container> 311 | <Component class="javax.swing.JLabel" name="jLabel14"> 312 | <Properties> 313 | <Property name="text" type="java.lang.String" value="Request data"/> 314 | </Properties> 315 | </Component> 316 | <Component class="javax.swing.JLabel" name="jLabel15"> 317 | <Properties> 318 | <Property name="text" type="java.lang.String" value="Implementation:"/> 319 | </Properties> 320 | </Component> 321 | <Component class="javax.swing.JComboBox" name="implementationComboBox"> 322 | <Properties> 323 | <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> 324 | <StringArray count="1"> 325 | <StringItem index="0" value="RFC6455 (v13)"/> 326 | </StringArray> 327 | </Property> 328 | </Properties> 329 | </Component> 330 | <Component class="javax.swing.JCheckBox" name="streamingConnectionCheckBox"> 331 | <Properties> 332 | <Property name="text" type="java.lang.String" value="Streaming connection"/> 333 | </Properties> 334 | </Component> 335 | </SubComponents> 336 | </Container> 337 | <Container class="javax.swing.JPanel" name="jPanel5"> 338 | <Properties> 339 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 340 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 341 | <TitledBorder title="WebSocket Response"/> 342 | </Border> 343 | </Property> 344 | </Properties> 345 | 346 | <Layout> 347 | <DimensionLayout dim="0"> 348 | <Group type="103" groupAlignment="0" attributes="0"> 349 | <Group type="102" attributes="0"> 350 | <EmptySpace max="-2" attributes="0"/> 351 | <Group type="103" groupAlignment="0" attributes="0"> 352 | <Group type="102" alignment="0" attributes="0"> 353 | <Component id="jLabel7" min="-2" max="-2" attributes="0"/> 354 | <EmptySpace max="-2" attributes="0"/> 355 | <Component id="responsePatternTextField" max="32767" attributes="0"/> 356 | <EmptySpace type="unrelated" max="-2" attributes="0"/> 357 | <Component id="overrideResponsePatternCheckBox" min="-2" max="-2" attributes="0"/> 358 | <EmptySpace min="-2" pref="6" max="-2" attributes="0"/> 359 | <Component id="jLabel16" min="-2" max="-2" attributes="0"/> 360 | <EmptySpace min="-2" max="-2" attributes="0"/> 361 | <Component id="messageBacklogTextField" min="-2" pref="40" max="-2" attributes="0"/> 362 | </Group> 363 | <Group type="102" alignment="1" attributes="0"> 364 | <Component id="jLabel9" min="-2" max="-2" attributes="0"/> 365 | <EmptySpace max="-2" attributes="0"/> 366 | <Component id="closeConncectionPatternTextField" max="32767" attributes="0"/> 367 | <EmptySpace max="-2" attributes="0"/> 368 | <Component id="overrideDisconnectPatternCheckBox" min="-2" max="-2" attributes="0"/> 369 | </Group> 370 | </Group> 371 | <EmptySpace max="-2" attributes="0"/> 372 | </Group> 373 | </Group> 374 | </DimensionLayout> 375 | <DimensionLayout dim="1"> 376 | <Group type="103" groupAlignment="0" attributes="0"> 377 | <Group type="102" alignment="0" attributes="0"> 378 | <EmptySpace max="-2" attributes="0"/> 379 | <Group type="103" groupAlignment="0" attributes="0"> 380 | <Group type="103" alignment="0" groupAlignment="3" attributes="0"> 381 | <Component id="jLabel16" alignment="3" min="-2" max="-2" attributes="0"/> 382 | <Component id="messageBacklogTextField" alignment="3" min="-2" max="-2" attributes="0"/> 383 | <Component id="overrideResponsePatternCheckBox" alignment="3" min="-2" max="-2" attributes="0"/> 384 | </Group> 385 | <Group type="103" groupAlignment="3" attributes="0"> 386 | <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> 387 | <Component id="responsePatternTextField" alignment="3" min="-2" max="-2" attributes="0"/> 388 | </Group> 389 | </Group> 390 | <EmptySpace max="-2" attributes="0"/> 391 | <Group type="103" groupAlignment="3" attributes="0"> 392 | <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> 393 | <Component id="closeConncectionPatternTextField" alignment="3" min="-2" max="-2" attributes="0"/> 394 | <Component id="overrideDisconnectPatternCheckBox" alignment="3" min="-2" max="-2" attributes="0"/> 395 | </Group> 396 | <EmptySpace max="32767" attributes="0"/> 397 | </Group> 398 | </Group> 399 | </DimensionLayout> 400 | </Layout> 401 | <SubComponents> 402 | <Component class="javax.swing.JLabel" name="jLabel7"> 403 | <Properties> 404 | <Property name="text" type="java.lang.String" value="Response pattern:"/> 405 | </Properties> 406 | </Component> 407 | <Component class="javax.swing.JTextField" name="responsePatternTextField"> 408 | </Component> 409 | <Component class="javax.swing.JLabel" name="jLabel9"> 410 | <Properties> 411 | <Property name="text" type="java.lang.String" value="Close connection pattern:"/> 412 | </Properties> 413 | </Component> 414 | <Component class="javax.swing.JTextField" name="closeConncectionPatternTextField"> 415 | </Component> 416 | <Component class="javax.swing.JLabel" name="jLabel16"> 417 | <Properties> 418 | <Property name="text" type="java.lang.String" value="Message backlog:"/> 419 | </Properties> 420 | </Component> 421 | <Component class="javax.swing.JTextField" name="messageBacklogTextField"> 422 | </Component> 423 | <Component class="javax.swing.JCheckBox" name="overrideResponsePatternCheckBox"> 424 | <Properties> 425 | <Property name="text" type="java.lang.String" value="Override previous"/> 426 | </Properties> 427 | </Component> 428 | <Component class="javax.swing.JCheckBox" name="overrideDisconnectPatternCheckBox"> 429 | <Properties> 430 | <Property name="text" type="java.lang.String" value="Override previous"/> 431 | </Properties> 432 | </Component> 433 | </SubComponents> 434 | </Container> 435 | <Container class="javax.swing.JPanel" name="jPanel6"> 436 | <Properties> 437 | <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> 438 | <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> 439 | <TitledBorder title="Proxy Server (currently not supported by Jetty)"/> 440 | </Border> 441 | </Property> 442 | </Properties> 443 | 444 | <Layout> 445 | <DimensionLayout dim="0"> 446 | <Group type="103" groupAlignment="0" attributes="0"> 447 | <Group type="102" attributes="0"> 448 | <EmptySpace max="-2" attributes="0"/> 449 | <Component id="jLabel10" min="-2" max="-2" attributes="0"/> 450 | <EmptySpace max="-2" attributes="0"/> 451 | <Component id="proxyAddressTextField" max="32767" attributes="0"/> 452 | <EmptySpace type="unrelated" max="-2" attributes="0"/> 453 | <Component id="jLabel11" min="-2" max="-2" attributes="0"/> 454 | <EmptySpace max="-2" attributes="0"/> 455 | <Component id="proxyPortTextField" min="-2" pref="39" max="-2" attributes="0"/> 456 | <EmptySpace type="separate" max="-2" attributes="0"/> 457 | <Component id="jLabel12" min="-2" max="-2" attributes="0"/> 458 | <EmptySpace max="-2" attributes="0"/> 459 | <Component id="proxyUsernameTextField" min="-2" pref="64" max="-2" attributes="0"/> 460 | <EmptySpace min="-2" pref="18" max="-2" attributes="0"/> 461 | <Component id="jLabel13" min="-2" max="-2" attributes="0"/> 462 | <EmptySpace max="-2" attributes="0"/> 463 | <Component id="proxyPasswordTextField" min="-2" pref="64" max="-2" attributes="0"/> 464 | <EmptySpace max="-2" attributes="0"/> 465 | </Group> 466 | </Group> 467 | </DimensionLayout> 468 | <DimensionLayout dim="1"> 469 | <Group type="103" groupAlignment="0" attributes="0"> 470 | <Group type="102" attributes="0"> 471 | <EmptySpace max="-2" attributes="0"/> 472 | <Group type="103" groupAlignment="0" attributes="0"> 473 | <Group type="103" alignment="0" groupAlignment="3" attributes="0"> 474 | <Component id="proxyUsernameTextField" alignment="3" min="-2" max="-2" attributes="0"/> 475 | <Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/> 476 | </Group> 477 | <Group type="103" groupAlignment="3" attributes="0"> 478 | <Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/> 479 | <Component id="proxyPortTextField" alignment="3" min="-2" max="-2" attributes="0"/> 480 | </Group> 481 | <Group type="103" groupAlignment="3" attributes="0"> 482 | <Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> 483 | <Component id="proxyAddressTextField" alignment="3" min="-2" max="-2" attributes="0"/> 484 | <Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> 485 | <Component id="proxyPasswordTextField" alignment="3" min="-2" max="-2" attributes="0"/> 486 | </Group> 487 | </Group> 488 | <EmptySpace max="32767" attributes="0"/> 489 | </Group> 490 | </Group> 491 | </DimensionLayout> 492 | </Layout> 493 | <SubComponents> 494 | <Component class="javax.swing.JLabel" name="jLabel10"> 495 | <Properties> 496 | <Property name="text" type="java.lang.String" value="Server Name or IP:"/> 497 | </Properties> 498 | </Component> 499 | <Component class="javax.swing.JTextField" name="proxyAddressTextField"> 500 | <Properties> 501 | <Property name="enabled" type="boolean" value="false"/> 502 | </Properties> 503 | </Component> 504 | <Component class="javax.swing.JLabel" name="jLabel11"> 505 | <Properties> 506 | <Property name="text" type="java.lang.String" value="Port Number:"/> 507 | </Properties> 508 | </Component> 509 | <Component class="javax.swing.JTextField" name="proxyPortTextField"> 510 | <Properties> 511 | <Property name="enabled" type="boolean" value="false"/> 512 | </Properties> 513 | </Component> 514 | <Component class="javax.swing.JLabel" name="jLabel12"> 515 | <Properties> 516 | <Property name="text" type="java.lang.String" value="Username:"/> 517 | </Properties> 518 | </Component> 519 | <Component class="javax.swing.JTextField" name="proxyUsernameTextField"> 520 | <Properties> 521 | <Property name="enabled" type="boolean" value="false"/> 522 | </Properties> 523 | </Component> 524 | <Component class="javax.swing.JLabel" name="jLabel13"> 525 | <Properties> 526 | <Property name="text" type="java.lang.String" value="Password:"/> 527 | </Properties> 528 | </Component> 529 | <Component class="javax.swing.JTextField" name="proxyPasswordTextField"> 530 | <Properties> 531 | <Property name="enabled" type="boolean" value="false"/> 532 | </Properties> 533 | </Component> 534 | </SubComponents> 535 | </Container> 536 | </SubComponents> 537 | </Form> 538 | -------------------------------------------------------------------------------- /src/main/java/JMeter/plugins/functional/samplers/websocket/WebSocketSamplerPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package JMeter.plugins.functional.samplers.websocket; 6 | 7 | import java.awt.Color; 8 | import org.apache.jmeter.config.gui.ArgumentsPanel; 9 | import org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel; 10 | import org.apache.jorphan.logging.LoggingManager; 11 | import org.apache.log.Logger; 12 | 13 | /** 14 | * 15 | * @author Maciej Zaleski 16 | */ 17 | public class WebSocketSamplerPanel extends javax.swing.JPanel { 18 | private static final Logger log = LoggingManager.getLoggerForClass(); 19 | private HTTPArgumentsPanel attributePanel; 20 | 21 | /** 22 | * Creates new form WebSocketSamplerPanel 23 | */ 24 | public WebSocketSamplerPanel() { 25 | initComponents(); 26 | 27 | attributePanel = new HTTPArgumentsPanel(); 28 | querystringAttributesPanel.add(attributePanel); 29 | } 30 | 31 | /** 32 | * This method is called from within the constructor to initialize the form. 33 | * WARNING: Do NOT modify this code. The content of this method is always 34 | * regenerated by the Form Editor. 35 | */ 36 | @SuppressWarnings("unchecked") 37 | // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents 38 | private void initComponents() { 39 | 40 | jPanel1 = new javax.swing.JPanel(); 41 | jLabel1 = new javax.swing.JLabel(); 42 | serverAddressTextField = new javax.swing.JTextField(); 43 | jLabel2 = new javax.swing.JLabel(); 44 | serverPortTextField = new javax.swing.JTextField(); 45 | jPanel2 = new javax.swing.JPanel(); 46 | jLabel3 = new javax.swing.JLabel(); 47 | connectionTimeoutTextField = new javax.swing.JTextField(); 48 | jLabel17 = new javax.swing.JLabel(); 49 | responseTimeoutTextField = new javax.swing.JTextField(); 50 | jPanel3 = new javax.swing.JPanel(); 51 | jLabel4 = new javax.swing.JLabel(); 52 | jLabel5 = new javax.swing.JLabel(); 53 | jLabel6 = new javax.swing.JLabel(); 54 | contextPathTextField = new javax.swing.JTextField(); 55 | protocolTextField = new javax.swing.JTextField(); 56 | contentEncodingTextField = new javax.swing.JTextField(); 57 | jLabel8 = new javax.swing.JLabel(); 58 | connectionIdTextField = new javax.swing.JTextField(); 59 | querystringAttributesPanel = new javax.swing.JPanel(); 60 | ignoreSslErrorsCheckBox = new javax.swing.JCheckBox(); 61 | jScrollPane1 = new javax.swing.JScrollPane(); 62 | requestPayloadEditorPane = new javax.swing.JEditorPane(); 63 | jLabel14 = new javax.swing.JLabel(); 64 | jLabel15 = new javax.swing.JLabel(); 65 | implementationComboBox = new javax.swing.JComboBox(); 66 | streamingConnectionCheckBox = new javax.swing.JCheckBox(); 67 | jPanel5 = new javax.swing.JPanel(); 68 | jLabel7 = new javax.swing.JLabel(); 69 | responsePatternTextField = new javax.swing.JTextField(); 70 | jLabel9 = new javax.swing.JLabel(); 71 | closeConncectionPatternTextField = new javax.swing.JTextField(); 72 | jLabel16 = new javax.swing.JLabel(); 73 | messageBacklogTextField = new javax.swing.JTextField(); 74 | overrideResponsePatternCheckBox = new javax.swing.JCheckBox(); 75 | overrideDisconnectPatternCheckBox = new javax.swing.JCheckBox(); 76 | jPanel6 = new javax.swing.JPanel(); 77 | jLabel10 = new javax.swing.JLabel(); 78 | proxyAddressTextField = new javax.swing.JTextField(); 79 | jLabel11 = new javax.swing.JLabel(); 80 | proxyPortTextField = new javax.swing.JTextField(); 81 | jLabel12 = new javax.swing.JLabel(); 82 | proxyUsernameTextField = new javax.swing.JTextField(); 83 | jLabel13 = new javax.swing.JLabel(); 84 | proxyPasswordTextField = new javax.swing.JTextField(); 85 | 86 | jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Web Server")); 87 | 88 | jLabel1.setText("Server Name or IP:"); 89 | 90 | jLabel2.setText("Port Number:"); 91 | 92 | javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 93 | jPanel1.setLayout(jPanel1Layout); 94 | jPanel1Layout.setHorizontalGroup( 95 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 96 | .addGroup(jPanel1Layout.createSequentialGroup() 97 | .addContainerGap() 98 | .addComponent(jLabel1) 99 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 100 | .addComponent(serverAddressTextField) 101 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 102 | .addComponent(jLabel2) 103 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 104 | .addComponent(serverPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE) 105 | .addContainerGap()) 106 | ); 107 | jPanel1Layout.setVerticalGroup( 108 | jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 109 | .addGroup(jPanel1Layout.createSequentialGroup() 110 | .addContainerGap() 111 | .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 112 | .addComponent(jLabel1) 113 | .addComponent(serverAddressTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 114 | .addComponent(jLabel2) 115 | .addComponent(serverPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 116 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 117 | ); 118 | 119 | jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Timeout (milliseconds)")); 120 | 121 | jLabel3.setText("Connection:"); 122 | 123 | jLabel17.setText("Response:"); 124 | 125 | javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); 126 | jPanel2.setLayout(jPanel2Layout); 127 | jPanel2Layout.setHorizontalGroup( 128 | jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 129 | .addGroup(jPanel2Layout.createSequentialGroup() 130 | .addContainerGap() 131 | .addComponent(jLabel3) 132 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 133 | .addComponent(connectionTimeoutTextField) 134 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 135 | .addComponent(jLabel17) 136 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 137 | .addComponent(responseTimeoutTextField) 138 | .addContainerGap()) 139 | ); 140 | jPanel2Layout.setVerticalGroup( 141 | jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 142 | .addGroup(jPanel2Layout.createSequentialGroup() 143 | .addContainerGap() 144 | .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 145 | .addComponent(jLabel3) 146 | .addComponent(connectionTimeoutTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 147 | .addComponent(jLabel17) 148 | .addComponent(responseTimeoutTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 149 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 150 | ); 151 | 152 | jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("WebSocket Request")); 153 | 154 | jLabel4.setText("Protocol [ws/wss]:"); 155 | 156 | jLabel5.setText("Path:"); 157 | 158 | jLabel6.setText("Content encoding:"); 159 | 160 | protocolTextField.setToolTipText(""); 161 | 162 | jLabel8.setText("Connection Id:"); 163 | 164 | querystringAttributesPanel.setLayout(new javax.swing.BoxLayout(querystringAttributesPanel, javax.swing.BoxLayout.LINE_AXIS)); 165 | 166 | ignoreSslErrorsCheckBox.setText("Ignore SSL certificate errors"); 167 | 168 | jScrollPane1.setViewportView(requestPayloadEditorPane); 169 | 170 | jLabel14.setText("Request data"); 171 | 172 | jLabel15.setText("Implementation:"); 173 | 174 | implementationComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "RFC6455 (v13)" })); 175 | 176 | streamingConnectionCheckBox.setText("Streaming connection"); 177 | 178 | javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); 179 | jPanel3.setLayout(jPanel3Layout); 180 | jPanel3Layout.setHorizontalGroup( 181 | jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 182 | .addGroup(jPanel3Layout.createSequentialGroup() 183 | .addContainerGap() 184 | .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 185 | .addComponent(querystringAttributesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 186 | .addComponent(jScrollPane1) 187 | .addGroup(jPanel3Layout.createSequentialGroup() 188 | .addComponent(jLabel15) 189 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 190 | .addComponent(implementationComboBox, 0, 1, Short.MAX_VALUE) 191 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 192 | .addComponent(jLabel4) 193 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 194 | .addComponent(protocolTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) 195 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 196 | .addComponent(jLabel6) 197 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 198 | .addComponent(contentEncodingTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) 199 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 200 | .addComponent(jLabel8) 201 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 202 | .addComponent(connectionIdTextField)) 203 | .addGroup(jPanel3Layout.createSequentialGroup() 204 | .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 205 | .addComponent(jLabel14) 206 | .addGroup(jPanel3Layout.createSequentialGroup() 207 | .addComponent(ignoreSslErrorsCheckBox) 208 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 209 | .addComponent(streamingConnectionCheckBox))) 210 | .addGap(0, 0, Short.MAX_VALUE)) 211 | .addGroup(jPanel3Layout.createSequentialGroup() 212 | .addComponent(jLabel5) 213 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 214 | .addComponent(contextPathTextField))) 215 | .addContainerGap()) 216 | ); 217 | jPanel3Layout.setVerticalGroup( 218 | jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 219 | .addGroup(jPanel3Layout.createSequentialGroup() 220 | .addGap(10, 10, 10) 221 | .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 222 | .addComponent(jLabel4) 223 | .addComponent(protocolTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 224 | .addComponent(jLabel6) 225 | .addComponent(contentEncodingTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 226 | .addComponent(jLabel8) 227 | .addComponent(connectionIdTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 228 | .addComponent(jLabel15) 229 | .addComponent(implementationComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 230 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 231 | .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 232 | .addComponent(jLabel5) 233 | .addComponent(contextPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 234 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 235 | .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 236 | .addComponent(ignoreSslErrorsCheckBox) 237 | .addComponent(streamingConnectionCheckBox)) 238 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 239 | .addComponent(querystringAttributesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE) 240 | .addGap(8, 8, 8) 241 | .addComponent(jLabel14) 242 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 243 | .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE) 244 | .addContainerGap()) 245 | ); 246 | 247 | jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("WebSocket Response")); 248 | 249 | jLabel7.setText("Response pattern:"); 250 | 251 | jLabel9.setText("Close connection pattern:"); 252 | 253 | jLabel16.setText("Message backlog:"); 254 | 255 | overrideResponsePatternCheckBox.setText("Override previous"); 256 | 257 | overrideDisconnectPatternCheckBox.setText("Override previous"); 258 | 259 | javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); 260 | jPanel5.setLayout(jPanel5Layout); 261 | jPanel5Layout.setHorizontalGroup( 262 | jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 263 | .addGroup(jPanel5Layout.createSequentialGroup() 264 | .addContainerGap() 265 | .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 266 | .addGroup(jPanel5Layout.createSequentialGroup() 267 | .addComponent(jLabel7) 268 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 269 | .addComponent(responsePatternTextField) 270 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 271 | .addComponent(overrideResponsePatternCheckBox) 272 | .addGap(6, 6, 6) 273 | .addComponent(jLabel16) 274 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 275 | .addComponent(messageBacklogTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)) 276 | .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel5Layout.createSequentialGroup() 277 | .addComponent(jLabel9) 278 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 279 | .addComponent(closeConncectionPatternTextField) 280 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 281 | .addComponent(overrideDisconnectPatternCheckBox))) 282 | .addContainerGap()) 283 | ); 284 | jPanel5Layout.setVerticalGroup( 285 | jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 286 | .addGroup(jPanel5Layout.createSequentialGroup() 287 | .addContainerGap() 288 | .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 289 | .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 290 | .addComponent(jLabel16) 291 | .addComponent(messageBacklogTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 292 | .addComponent(overrideResponsePatternCheckBox)) 293 | .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 294 | .addComponent(jLabel7) 295 | .addComponent(responsePatternTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) 296 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 297 | .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 298 | .addComponent(jLabel9) 299 | .addComponent(closeConncectionPatternTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 300 | .addComponent(overrideDisconnectPatternCheckBox)) 301 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 302 | ); 303 | 304 | jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder("Proxy Server (currently not supported by Jetty)")); 305 | 306 | jLabel10.setText("Server Name or IP:"); 307 | 308 | proxyAddressTextField.setEnabled(false); 309 | 310 | jLabel11.setText("Port Number:"); 311 | 312 | proxyPortTextField.setEnabled(false); 313 | 314 | jLabel12.setText("Username:"); 315 | 316 | proxyUsernameTextField.setEnabled(false); 317 | 318 | jLabel13.setText("Password:"); 319 | 320 | proxyPasswordTextField.setEnabled(false); 321 | 322 | javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); 323 | jPanel6.setLayout(jPanel6Layout); 324 | jPanel6Layout.setHorizontalGroup( 325 | jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 326 | .addGroup(jPanel6Layout.createSequentialGroup() 327 | .addContainerGap() 328 | .addComponent(jLabel10) 329 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 330 | .addComponent(proxyAddressTextField) 331 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 332 | .addComponent(jLabel11) 333 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 334 | .addComponent(proxyPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE) 335 | .addGap(18, 18, 18) 336 | .addComponent(jLabel12) 337 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 338 | .addComponent(proxyUsernameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) 339 | .addGap(18, 18, 18) 340 | .addComponent(jLabel13) 341 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 342 | .addComponent(proxyPasswordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) 343 | .addContainerGap()) 344 | ); 345 | jPanel6Layout.setVerticalGroup( 346 | jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 347 | .addGroup(jPanel6Layout.createSequentialGroup() 348 | .addContainerGap() 349 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 350 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 351 | .addComponent(proxyUsernameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 352 | .addComponent(jLabel12)) 353 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 354 | .addComponent(jLabel11) 355 | .addComponent(proxyPortTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 356 | .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 357 | .addComponent(jLabel10) 358 | .addComponent(proxyAddressTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 359 | .addComponent(jLabel13) 360 | .addComponent(proxyPasswordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) 361 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 362 | ); 363 | 364 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 365 | this.setLayout(layout); 366 | layout.setHorizontalGroup( 367 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 368 | .addGroup(layout.createSequentialGroup() 369 | .addContainerGap() 370 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 371 | .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 372 | .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 373 | .addGroup(layout.createSequentialGroup() 374 | .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 375 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 376 | .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 377 | .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 378 | .addContainerGap()) 379 | ); 380 | layout.setVerticalGroup( 381 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 382 | .addGroup(layout.createSequentialGroup() 383 | .addContainerGap() 384 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 385 | .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 386 | .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 387 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 388 | .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 389 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 390 | .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 391 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 392 | .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 393 | .addContainerGap()) 394 | ); 395 | }// </editor-fold>//GEN-END:initComponents 396 | // Variables declaration - do not modify//GEN-BEGIN:variables 397 | private javax.swing.JTextField closeConncectionPatternTextField; 398 | private javax.swing.JTextField connectionIdTextField; 399 | private javax.swing.JTextField connectionTimeoutTextField; 400 | private javax.swing.JTextField contentEncodingTextField; 401 | private javax.swing.JTextField contextPathTextField; 402 | private javax.swing.JCheckBox ignoreSslErrorsCheckBox; 403 | private javax.swing.JComboBox implementationComboBox; 404 | private javax.swing.JLabel jLabel1; 405 | private javax.swing.JLabel jLabel10; 406 | private javax.swing.JLabel jLabel11; 407 | private javax.swing.JLabel jLabel12; 408 | private javax.swing.JLabel jLabel13; 409 | private javax.swing.JLabel jLabel14; 410 | private javax.swing.JLabel jLabel15; 411 | private javax.swing.JLabel jLabel16; 412 | private javax.swing.JLabel jLabel17; 413 | private javax.swing.JLabel jLabel2; 414 | private javax.swing.JLabel jLabel3; 415 | private javax.swing.JLabel jLabel4; 416 | private javax.swing.JLabel jLabel5; 417 | private javax.swing.JLabel jLabel6; 418 | private javax.swing.JLabel jLabel7; 419 | private javax.swing.JLabel jLabel8; 420 | private javax.swing.JLabel jLabel9; 421 | private javax.swing.JPanel jPanel1; 422 | private javax.swing.JPanel jPanel2; 423 | private javax.swing.JPanel jPanel3; 424 | private javax.swing.JPanel jPanel5; 425 | private javax.swing.JPanel jPanel6; 426 | private javax.swing.JScrollPane jScrollPane1; 427 | private javax.swing.JTextField messageBacklogTextField; 428 | private javax.swing.JCheckBox overrideDisconnectPatternCheckBox; 429 | private javax.swing.JCheckBox overrideResponsePatternCheckBox; 430 | private javax.swing.JTextField protocolTextField; 431 | private javax.swing.JTextField proxyAddressTextField; 432 | private javax.swing.JTextField proxyPasswordTextField; 433 | private javax.swing.JTextField proxyPortTextField; 434 | private javax.swing.JTextField proxyUsernameTextField; 435 | private javax.swing.JPanel querystringAttributesPanel; 436 | private javax.swing.JEditorPane requestPayloadEditorPane; 437 | private javax.swing.JTextField responsePatternTextField; 438 | private javax.swing.JTextField responseTimeoutTextField; 439 | private javax.swing.JTextField serverAddressTextField; 440 | private javax.swing.JTextField serverPortTextField; 441 | private javax.swing.JCheckBox streamingConnectionCheckBox; 442 | // End of variables declaration//GEN-END:variables 443 | 444 | public void initFields() { 445 | } 446 | 447 | public void setCloseConncectionPattern(String closeConncectionPattern) { 448 | closeConncectionPatternTextField.setText(closeConncectionPattern); 449 | } 450 | 451 | public String getCloseConncectionPattern() { 452 | return closeConncectionPatternTextField.getText(); 453 | } 454 | 455 | public void setConnectionId(String connectionId) { 456 | connectionIdTextField.setText(connectionId); 457 | } 458 | 459 | public String getConnectionId() { 460 | return connectionIdTextField.getText(); 461 | } 462 | 463 | public void setContentEncoding(String contentEncoding) { 464 | contentEncodingTextField.setText(contentEncoding); 465 | } 466 | 467 | public String getContentEncoding() { 468 | return contentEncodingTextField.getText(); 469 | } 470 | 471 | public void setContextPath(String contextPath) { 472 | contextPathTextField.setText(contextPath); 473 | } 474 | 475 | public String getContextPath() { 476 | return contextPathTextField.getText(); 477 | } 478 | 479 | public void setProtocol(String protocol) { 480 | protocolTextField.setText(protocol); 481 | } 482 | 483 | public String getProtocol() { 484 | return protocolTextField.getText(); 485 | } 486 | 487 | public void setProxyAddress(String proxyAddress) { 488 | proxyAddressTextField.setText(proxyAddress); 489 | } 490 | 491 | public String getProxyAddress() { 492 | return proxyAddressTextField.getText(); 493 | } 494 | 495 | public void setProxyPassword(String proxyPassword) { 496 | proxyPasswordTextField.setText(proxyPassword); 497 | } 498 | 499 | public String getProxyPassword() { 500 | return proxyPasswordTextField.getText(); 501 | } 502 | 503 | public void setProxyPort(String proxyPort) { 504 | proxyPortTextField.setText(proxyPort); 505 | } 506 | 507 | public String getProxyPort() { 508 | return proxyPortTextField.getText(); 509 | } 510 | 511 | public void setProxyUsername(String proxyUsername) { 512 | proxyUsernameTextField.setText(proxyUsername); 513 | } 514 | 515 | public String getProxyUsername() { 516 | return proxyUsernameTextField.getText(); 517 | } 518 | 519 | public void setResponsePattern(String responsePattern) { 520 | responsePatternTextField.setText(responsePattern); 521 | } 522 | 523 | public String getResponsePattern() { 524 | return responsePatternTextField.getText(); 525 | } 526 | 527 | public void setResponseTimeout(String responseTimeout) { 528 | responseTimeoutTextField.setText(responseTimeout); 529 | } 530 | 531 | public String getResponseTimeout() { 532 | return responseTimeoutTextField.getText(); 533 | } 534 | 535 | public void setConnectionTimeout(String connectionTimeout) { 536 | connectionTimeoutTextField.setText(connectionTimeout); 537 | } 538 | 539 | public String getConnectionTimeout() { 540 | return connectionTimeoutTextField.getText(); 541 | } 542 | 543 | public void setServerAddress(String serverAddress) { 544 | serverAddressTextField.setText(serverAddress); 545 | } 546 | 547 | public String getServerAddress() { 548 | return serverAddressTextField.getText(); 549 | } 550 | 551 | public void setServerPort(String serverPort) { 552 | serverPortTextField.setText(serverPort); 553 | } 554 | 555 | public String getServerPort() { 556 | return serverPortTextField.getText(); 557 | } 558 | 559 | public void setRequestPayload(String requestPayload) { 560 | requestPayloadEditorPane.setText(requestPayload); 561 | } 562 | 563 | public String getRequestPayload() { 564 | return requestPayloadEditorPane.getText(); 565 | } 566 | 567 | public void setStreamingConnection(Boolean streamingConnection) { 568 | streamingConnectionCheckBox.setSelected(streamingConnection); 569 | } 570 | 571 | public Boolean isStreamingConnection() { 572 | return streamingConnectionCheckBox.isSelected(); 573 | } 574 | 575 | public void setIgnoreSslErrors(Boolean ignoreSslErrors) { 576 | ignoreSslErrorsCheckBox.setSelected(ignoreSslErrors); 577 | } 578 | 579 | public Boolean isIgnoreSslErrors() { 580 | return ignoreSslErrorsCheckBox.isSelected(); 581 | } 582 | 583 | public void setImplementation(String implementation) { 584 | implementationComboBox.setSelectedItem(implementation); 585 | } 586 | 587 | public String getImplementation() { 588 | return (String) implementationComboBox.getSelectedItem(); 589 | } 590 | 591 | public void setMessageBacklog(String messageBacklog) { 592 | messageBacklogTextField.setText(messageBacklog); 593 | } 594 | 595 | public String getMessageBacklog() { 596 | return messageBacklogTextField.getText(); 597 | } 598 | 599 | public void setOverrideResponsePattern(Boolean overrideResponsePattern) { 600 | overrideResponsePatternCheckBox.setSelected(overrideResponsePattern); 601 | } 602 | 603 | public Boolean isOverrideResponsePattern() { 604 | return overrideResponsePatternCheckBox.isSelected(); 605 | } 606 | 607 | public void setOverrideDisconnectPattern(Boolean overrideDisconnectPattern) { 608 | overrideDisconnectPatternCheckBox.setSelected(overrideDisconnectPattern); 609 | } 610 | 611 | public Boolean isOverrideDisconnectPattern() { 612 | return overrideDisconnectPatternCheckBox.isSelected(); 613 | } 614 | 615 | /** 616 | * @return the attributePanel 617 | */ 618 | public ArgumentsPanel getAttributePanel() { 619 | return attributePanel; 620 | } 621 | } 622 | --------------------------------------------------------------------------------