001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.protocol.http.control.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Dimension;
023: import java.awt.Font;
024: import java.awt.event.ActionEvent;
025:
026: import javax.swing.JButton;
027: import javax.swing.JCheckBox;
028: import javax.swing.JOptionPane;
029: import javax.swing.JLabel;
030: import javax.swing.JPanel;
031: import javax.swing.border.Border;
032: import javax.swing.border.EmptyBorder;
033:
034: import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
035: import org.apache.jmeter.protocol.http.sampler.WebServiceSampler;
036: import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
037: import org.apache.jmeter.testelement.TestElement;
038: import org.apache.jmeter.util.JMeterUtils;
039: import org.apache.jmeter.gui.util.FilePanel;
040: import org.apache.jorphan.gui.JLabeledChoice;
041: import org.apache.jorphan.gui.JLabeledTextArea;
042: import org.apache.jorphan.gui.JLabeledTextField;
043: import org.apache.jorphan.gui.layout.VerticalLayout;
044: import org.apache.jmeter.protocol.http.util.WSDLHelper;
045: import org.apache.jmeter.protocol.http.control.AuthManager;
046:
047: /**
048: * This is the GUI for the webservice samplers. It extends AbstractSamplerGui
049: * and is modeled after the SOAP sampler GUI. I've added instructional notes to
050: * the GUI for instructional purposes. XML parsing is pretty heavy weight,
051: * therefore the notes address those situations. <br>
052: * Created on: Jun 26, 2003
053: *
054: */
055: public class WebServiceSamplerGui extends AbstractSamplerGui implements
056: java.awt.event.ActionListener {
057:
058: private JLabeledTextField domain = new JLabeledTextField(
059: JMeterUtils.getResString("web_server_domain")); // $NON-NLS-1$
060:
061: private JLabeledTextField protocol = new JLabeledTextField(
062: JMeterUtils.getResString("protocol")); // $NON-NLS-1$
063:
064: private JLabeledTextField port = new JLabeledTextField(JMeterUtils
065: .getResString("web_server_port")); // $NON-NLS-1$
066:
067: private JLabeledTextField path = new JLabeledTextField(JMeterUtils
068: .getResString("path")); // $NON-NLS-1$
069:
070: private JLabeledTextField soapAction = new JLabeledTextField(
071: JMeterUtils.getResString("webservice_soap_action")); // $NON-NLS-1$
072:
073: private JLabeledTextArea soapXml = new JLabeledTextArea(JMeterUtils
074: .getResString("soap_data_title")); // $NON-NLS-1$
075:
076: private JLabeledTextField wsdlField = new JLabeledTextField(
077: JMeterUtils.getResString("wsdl_url")); // $NON-NLS-1$
078:
079: private JButton wsdlButton = new JButton(JMeterUtils
080: .getResString("load_wsdl")); // $NON-NLS-1$
081:
082: private JButton selectButton = new JButton(JMeterUtils
083: .getResString("configure_wsdl")); // $NON-NLS-1$
084:
085: private JLabeledChoice wsdlMethods = null;
086:
087: private transient WSDLHelper HELPER = null;
088:
089: private FilePanel soapXmlFile = new FilePanel(JMeterUtils
090: .getResString("get_xml_from_file"), ".xml"); // $NON-NLS-1$
091:
092: private JLabeledTextField randomXmlFile = new JLabeledTextField(
093: JMeterUtils.getResString("get_xml_from_random")); // $NON-NLS-1$
094:
095: private JLabeledTextField connectTimeout = new JLabeledTextField(
096: JMeterUtils.getResString("webservice_timeout")); // $NON-NLS-1$
097:
098: /**
099: * We create several JLabel objects to display usage instructions in the
100: * GUI. The reason there are multiple labels is to make sure it displays
101: * correctly.
102: */
103: private JLabel wsdlMessage = new JLabel(JMeterUtils
104: .getResString("get_xml_message")); // $NON-NLS-1$
105:
106: private JLabel wsdlMessage2 = new JLabel(JMeterUtils
107: .getResString("get_xml_message2")); // $NON-NLS-1$
108:
109: private JLabel wsdlMessage3 = new JLabel(JMeterUtils
110: .getResString("get_xml_message3")); // $NON-NLS-1$
111:
112: private JLabel wsdlMessage4 = new JLabel(JMeterUtils
113: .getResString("get_xml_message4")); // $NON-NLS-1$
114:
115: private JLabel wsdlMessage5 = new JLabel(JMeterUtils
116: .getResString("get_xml_message5")); // $NON-NLS-1$
117:
118: /**
119: * This is the font for the note.
120: */
121: private Font plainText = new Font("plain", Font.PLAIN, 10); // $NON-NLS-1$
122:
123: /**
124: * checkbox for memory cache.
125: */
126: private JCheckBox memCache = new JCheckBox(JMeterUtils
127: .getResString("memory_cache"), true); // $NON-NLS-1$
128:
129: /**
130: * checkbox for reading the response
131: */
132: private JCheckBox readResponse = new JCheckBox(JMeterUtils
133: .getResString("read_soap_response")); // $NON-NLS-1$
134:
135: /**
136: * checkbox for use proxy
137: */
138: private JCheckBox useProxy = new JCheckBox(JMeterUtils
139: .getResString("webservice_use_proxy")); // $NON-NLS-1$
140:
141: /**
142: * text field for the proxy host
143: */
144: private JLabeledTextField proxyHost = new JLabeledTextField(
145: JMeterUtils.getResString("webservice_proxy_host")); // $NON-NLS-1$
146:
147: /**
148: * text field for the proxy port
149: */
150: private JLabeledTextField proxyPort = new JLabeledTextField(
151: JMeterUtils.getResString("webservice_proxy_port")); // $NON-NLS-1$
152:
153: /**
154: * Text note about read response and its usage.
155: */
156: private JLabel readMessage = new JLabel(JMeterUtils
157: .getResString("read_response_note")); // $NON-NLS-1$
158:
159: private JLabel readMessage2 = new JLabel(JMeterUtils
160: .getResString("read_response_note2")); // $NON-NLS-1$
161:
162: private JLabel readMessage3 = new JLabel(JMeterUtils
163: .getResString("read_response_note3")); // $NON-NLS-1$
164:
165: /**
166: * Text note for proxy
167: */
168: private JLabel proxyMessage = new JLabel(JMeterUtils
169: .getResString("webservice_proxy_note")); // $NON-NLS-1$
170:
171: private JLabel proxyMessage2 = new JLabel(JMeterUtils
172: .getResString("webservice_proxy_note2")); // $NON-NLS-1$
173:
174: private JLabel proxyMessage3 = new JLabel(JMeterUtils
175: .getResString("webservice_proxy_note3")); // $NON-NLS-1$
176:
177: public WebServiceSamplerGui() {
178: init();
179: }
180:
181: public String getLabelResource() {
182: return "webservice_sampler_title"; // $NON-NLS-1$
183: }
184:
185: /**
186: * @see org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
187: */
188: public TestElement createTestElement() {
189: WebServiceSampler sampler = new WebServiceSampler();
190: this .configureTestElement(sampler);
191: this .modifyTestElement(sampler);
192: return sampler;
193: }
194:
195: /**
196: * Modifies a given TestElement to mirror the data in the gui components.
197: *
198: * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
199: */
200: public void modifyTestElement(TestElement s) {
201: WebServiceSampler sampler = (WebServiceSampler) s;
202: this .configureTestElement(sampler);
203: sampler.setDomain(domain.getText());
204: sampler.setProperty(HTTPSamplerBase.PORT, port.getText());
205: sampler.setProtocol(protocol.getText());
206: sampler.setPath(path.getText());
207: sampler.setWsdlURL(wsdlField.getText());
208: sampler.setMethod(HTTPSamplerBase.POST);
209: sampler.setSoapAction(soapAction.getText());
210: sampler.setXmlData(soapXml.getText());
211: sampler.setXmlFile(soapXmlFile.getFilename());
212: sampler.setXmlPathLoc(randomXmlFile.getText());
213: sampler.setTimeout(connectTimeout.getText());
214: sampler.setMemoryCache(memCache.isSelected());
215: sampler.setReadResponse(readResponse.isSelected());
216: sampler.setUseProxy(useProxy.isSelected());
217: sampler.setProxyHost(proxyHost.getText());
218: sampler.setProxyPort(proxyPort.getText());
219: }
220:
221: /**
222: * Implements JMeterGUIComponent.clearGui
223: */
224: public void clearGui() {
225: super .clearGui();
226:
227: domain.setText(""); //$NON-NLS-1$
228: protocol.setText(""); //$NON-NLS-1$
229: port.setText(""); //$NON-NLS-1$
230: path.setText(""); //$NON-NLS-1$
231: soapAction.setText(""); //$NON-NLS-1$
232: soapXml.setText(""); //$NON-NLS-1$
233: wsdlField.setText(""); //$NON-NLS-1$
234: randomXmlFile.setText(""); //$NON-NLS-1$
235: connectTimeout.setText(""); //$NON-NLS-1$
236: proxyHost.setText(""); //$NON-NLS-1$
237: proxyPort.setText(""); //$NON-NLS-1$
238: memCache.setSelected(true);
239: readResponse.setSelected(false);
240: useProxy.setSelected(false);
241: soapXmlFile.setFilename(""); //$NON-NLS-1$
242: }
243:
244: /**
245: * init() adds soapAction to the mainPanel. The class reuses logic from
246: * SOAPSampler, since it is common.
247: */
248: private void init() {
249: setLayout(new BorderLayout(0, 5));
250: setBorder(makeBorder());
251: add(makeTitlePanel(), BorderLayout.NORTH);
252:
253: wsdlMessage.setFont(plainText);
254: wsdlMessage2.setFont(plainText);
255: wsdlMessage3.setFont(plainText);
256: wsdlMessage4.setFont(plainText);
257: wsdlMessage5.setFont(plainText);
258: readMessage.setFont(plainText);
259: readMessage2.setFont(plainText);
260: readMessage3.setFont(plainText);
261:
262: // MAIN PANEL
263: JPanel mainPanel = new JPanel();
264: Border margin = new EmptyBorder(10, 10, 5, 10);
265: mainPanel.setBorder(margin);
266: mainPanel.setLayout(new VerticalLayout(5, VerticalLayout.BOTH));
267:
268: // Button for browsing webservice wsdl
269: JPanel wsdlEntry = new JPanel();
270: mainPanel.add(wsdlEntry);
271: wsdlEntry.add(wsdlField);
272: wsdlEntry.add(wsdlButton);
273: wsdlButton.addActionListener(this );
274:
275: // Web Methods
276: JPanel listPanel = new JPanel();
277: JLabel selectLabel = new JLabel("Web Methods");
278: wsdlMethods = new JLabeledChoice();
279: mainPanel.add(listPanel);
280: listPanel.add(selectLabel);
281: listPanel.add(wsdlMethods);
282: listPanel.add(selectButton);
283: selectButton.addActionListener(this );
284:
285: mainPanel.add(protocol);
286: mainPanel.add(domain);
287: mainPanel.add(port);
288: mainPanel.add(path);
289: mainPanel.add(connectTimeout);
290: mainPanel.add(soapAction);
291: // OPTIONAL TASKS
292: // we create a preferred size for the soap text area
293: // the width is the same as the soap file browser
294: Dimension pref = new Dimension(400, 200);
295: soapXml.setPreferredSize(pref);
296: mainPanel.add(soapXml);
297: mainPanel.add(soapXmlFile);
298: mainPanel.add(wsdlMessage);
299: mainPanel.add(wsdlMessage2);
300: mainPanel.add(wsdlMessage3);
301: mainPanel.add(wsdlMessage4);
302: mainPanel.add(wsdlMessage5);
303: mainPanel.add(randomXmlFile);
304: mainPanel.add(memCache);
305: mainPanel.add(readResponse);
306: mainPanel.add(readMessage);
307: mainPanel.add(readMessage2);
308: mainPanel.add(readMessage3);
309:
310: // add the proxy elements
311: mainPanel.add(useProxy);
312: useProxy.addActionListener(this );
313: mainPanel.add(proxyHost);
314: mainPanel.add(proxyPort);
315: // add the proxy notes
316: proxyMessage.setFont(plainText);
317: proxyMessage2.setFont(plainText);
318: proxyMessage3.setFont(plainText);
319: mainPanel.add(proxyMessage);
320: mainPanel.add(proxyMessage2);
321: mainPanel.add(proxyMessage3);
322:
323: this .add(mainPanel);
324: }
325:
326: /**
327: * the implementation loads the URL and the soap action for the request.
328: */
329: public void configure(TestElement el) {
330: super .configure(el);
331: WebServiceSampler sampler = (WebServiceSampler) el;
332: wsdlField.setText(sampler.getWsdlURL());
333: protocol.setText(sampler.getProtocol());
334: domain.setText(sampler.getDomain());
335: port.setText(sampler.getPropertyAsString(HTTPSamplerBase.PORT));
336: path.setText(sampler.getPath());
337: soapAction.setText(sampler.getSoapAction());
338: soapXml.setText(sampler.getXmlData());
339: soapXmlFile.setFilename(sampler.getXmlFile());
340: randomXmlFile.setText(sampler.getXmlPathLoc());
341: connectTimeout.setText(sampler.getTimeout());
342: memCache.setSelected(sampler.getMemoryCache());
343: readResponse.setSelected(sampler.getReadResponse());
344: useProxy.setSelected(sampler.getUseProxy());
345: if (sampler.getProxyHost().length() == 0) {
346: proxyHost.setEnabled(false);
347: } else {
348: proxyHost.setText(sampler.getProxyHost());
349: }
350: if (sampler.getProxyPort() == 0) {
351: proxyPort.setEnabled(false);
352: } else {
353: proxyPort.setText(String.valueOf(sampler.getProxyPort()));
354: }
355: }
356:
357: /**
358: * configure the sampler from the WSDL. If the WSDL did not include service
359: * node, it will use the original URL minus the querystring. That may not be
360: * correct, so we should probably add a note. For Microsoft webservices it
361: * will work, since that's how IIS works.
362: */
363: public void configureFromWSDL() {
364: if (HELPER != null) {
365: if (HELPER.getBinding() != null) {
366: this .protocol.setText(HELPER.getProtocol());
367: this .domain.setText(HELPER.getBindingHost());
368: if (HELPER.getBindingPort() > 0) {
369: this .port.setText(String.valueOf(HELPER
370: .getBindingPort()));
371: } else {
372: this .port.setText("80"); // $NON-NLS-1$
373: }
374: this .path.setText(HELPER.getBindingPath());
375: }
376: this .soapAction.setText(HELPER
377: .getSoapAction(this .wsdlMethods.getText()));
378: }
379: }
380:
381: /**
382: * The method uses WSDLHelper to get the information from the WSDL. Since
383: * the logic for getting the description is isolated to this method, we can
384: * easily replace it with a different WSDL driver later on.
385: *
386: * @param url
387: * @return array of web methods
388: */
389: public String[] browseWSDL(String url) {
390: try {
391: // We get the AuthManager and pass it to the WSDLHelper
392: // once the sampler is updated to Axis, all of this stuff
393: // should not be necessary. Now I just need to find the
394: // time and motivation to do it.
395: WebServiceSampler sampler = (WebServiceSampler) this
396: .createTestElement();
397: AuthManager manager = sampler.getAuthManager();
398: HELPER = new WSDLHelper(url, manager);
399: HELPER.parse();
400: return HELPER.getWebMethods();
401: } catch (Exception exception) {
402: JOptionPane.showConfirmDialog(this ,
403: JMeterUtils.getResString("wsdl_helper_error"), // $NON-NLS-1$
404: "Warning", JOptionPane.DEFAULT_OPTION,
405: JOptionPane.ERROR_MESSAGE);
406: return null;
407: }
408: }
409:
410: /**
411: * method from ActionListener
412: *
413: * @param event
414: * that occurred
415: */
416: public void actionPerformed(ActionEvent event) {
417: final Object eventSource = event.getSource();
418: if (eventSource == selectButton) {
419: this .configureFromWSDL();
420: } else if (eventSource == useProxy) {
421: // if use proxy is checked, we enable
422: // the text fields for the host and port
423: boolean use = useProxy.isSelected();
424: if (use) {
425: proxyHost.setEnabled(true);
426: proxyPort.setEnabled(true);
427: } else {
428: proxyHost.setEnabled(false);
429: proxyPort.setEnabled(false);
430: }
431: } else if (eventSource == wsdlButton) {
432: final String wsdlText = wsdlField.getText();
433: if (wsdlText != null && wsdlText.length() > 0) {
434: String[] wsdlData = browseWSDL(wsdlText);
435: if (wsdlData != null) {
436: wsdlMethods.setValues(wsdlData);
437: wsdlMethods.repaint();
438: }
439: } else {
440: JOptionPane.showConfirmDialog(this ,
441: JMeterUtils.getResString("wsdl_url_error"), // $NON-NLS-1$
442: "Warning", JOptionPane.DEFAULT_OPTION,
443: JOptionPane.ERROR_MESSAGE);
444: }
445: }
446: }
447:
448: }
|