Java tutorial
/* * soapUI, copyright (C) 2004-2012 smartbear.com * * soapUI is free software; you can redistribute it and/or modify it under the * terms of version 2.1 of the GNU Lesser General Public License as published by * the Free Software Foundation. * * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details at gnu.org. */ package com.eviware.soapui.impl.wsdl.monitor; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JToggleButton; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import org.apache.commons.collections.list.TreeList; import org.apache.http.HttpRequest; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.decorator.Filter; import org.jdesktop.swingx.decorator.FilterPipeline; import org.jdesktop.swingx.decorator.PatternFilter; import com.eviware.soapui.SoapUI; import com.eviware.soapui.impl.support.AbstractInterface; import com.eviware.soapui.impl.wsdl.WsdlInterface; import com.eviware.soapui.impl.wsdl.WsdlProject; import com.eviware.soapui.impl.wsdl.WsdlRequest; import com.eviware.soapui.impl.wsdl.WsdlTestSuite; import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction; import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction.LaunchForm; import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation; import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse; import com.eviware.soapui.impl.wsdl.mock.WsdlMockService; import com.eviware.soapui.impl.wsdl.support.HelpUrls; import com.eviware.soapui.impl.wsdl.support.MessageExchangeModelItem; import com.eviware.soapui.impl.wsdl.support.MessageExchangeRequestMessageEditor; import com.eviware.soapui.impl.wsdl.support.MessageExchangeResponseMessageEditor; import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase; import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequest; import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStep; import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequest; import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep; import com.eviware.soapui.impl.wsdl.teststeps.registry.HttpRequestStepFactory; import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory; import com.eviware.soapui.model.iface.Attachment; import com.eviware.soapui.model.iface.Interface; import com.eviware.soapui.model.settings.Settings; import com.eviware.soapui.model.support.ModelSupport; import com.eviware.soapui.model.testsuite.TestSuite; import com.eviware.soapui.settings.ProxySettings; import com.eviware.soapui.support.DateUtil; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.UISupport; import com.eviware.soapui.support.components.BrowserComponent; import com.eviware.soapui.support.components.JComponentInspector; import com.eviware.soapui.support.components.JInspectorPanel; import com.eviware.soapui.support.components.JInspectorPanelFactory; import com.eviware.soapui.support.components.JXToolBar; import com.eviware.soapui.support.types.StringList; import com.eviware.soapui.support.types.StringToStringsMap; import com.eviware.x.form.XFormDialog; import com.eviware.x.form.XFormField; import com.eviware.x.form.XFormFieldListener; import com.eviware.x.form.support.ADialogBuilder; import com.eviware.x.form.support.AField; import com.eviware.x.form.support.AField.AFieldType; import com.eviware.x.form.support.AForm; import com.jgoodies.forms.builder.ButtonBarBuilder; /** * A SOAP Monitor.. */ @SuppressWarnings("serial") public class SoapMonitor extends JPanel { private static final String ALL_FILTER_OPTION = "- all -"; private JProgressBar progressBar; private JButton stopButton = null; private JXTable logTable = null; private MonitorLogTableModel tableModel = null; private String httpProxyHost = null; private int httpProxyPort = 80; private JButton startButton; private final WsdlProject project; private MessageExchangeRequestMessageEditor requestViewer; private MessageExchangeResponseMessageEditor responseViewer; private SoapUIListenerSupport<MonitorListener> listeners = new SoapUIListenerSupport<MonitorListener>( MonitorListener.class); private MessageExchangeModelItem requestModelItem; private JButton optionsButton; private int listenPort; private String targetEndpoint; private JButton clearButton; private int maxRows; private JButton addToTestCaseButton; // private JButton addToRestTestCaseButton; private JButton createRequestButton; private JButton addToMockServiceButton; private Stack<WsdlMonitorMessageExchange> messageExchangeStack = new Stack<WsdlMonitorMessageExchange>(); private StackProcessor stackProcessor = new StackProcessor(); private PatternFilter operationFilter; private PatternFilter interfaceFilter; private PatternFilter targetHostFilter; private JLabel infoLabel; private PatternFilter requestHostFilter; private JComboBox requestHostFilterCombo; private JComboBox targetHostFilterCombo; private JComboBox interfaceFilterCombo; private JComboBox operationFilterCombo; private DefaultComboBoxModel operationFilterModel; private DefaultComboBoxModel requestFilterModel; private DefaultComboBoxModel targetHostFilterModel; private JLabel rowCountLabel = new JLabel(); private Map<AbstractInterface<?>, String> addedEndpoints; private JXToolBar toolbar; private String incomingRequestWss; private String incomingResponseWss; private boolean setAsProxy; private XFormDialog optionsDialog; private SoapMonitorEngine monitorEngine; private String oldProxyHost; private String oldProxyPort; private boolean oldProxyEnabled; private String sslEndpoint; private JInspectorPanel inspectorPanel; public SoapMonitor(WsdlProject project, int listenPort, String incomingRequestWss, String incomingResponseWss, JXToolBar mainToolbar, boolean setAsProxy, String sslEndpoint) { super(new BorderLayout()); this.project = project; this.listenPort = listenPort; this.incomingRequestWss = incomingRequestWss; this.incomingResponseWss = incomingResponseWss; this.setAsProxy = setAsProxy; this.maxRows = 100; this.sslEndpoint = sslEndpoint; // set the slow link to the passed down link this.setLayout(new BorderLayout()); add(buildToolbars(mainToolbar), BorderLayout.NORTH); add(buildContent(), BorderLayout.CENTER); start(); } public SoapMonitor(WsdlProject project, int sourcePort, String incomingRequestWss, String incomingResponseWss, JXToolBar toolbar, boolean setAsProxy) { this(project, sourcePort, incomingRequestWss, incomingResponseWss, toolbar, setAsProxy, null); } private JComponent buildContent() { inspectorPanel = JInspectorPanelFactory.build(buildLog()); JComponentInspector<JComponent> viewInspector = new JComponentInspector<JComponent>(buildViewer(), "Message Content", "Shows message content", true); inspectorPanel.addInspector(viewInspector); return inspectorPanel.getComponent(); } private JComponent buildLog() { tableModel = new MonitorLogTableModel(); logTable = new JXTable(1, 2); logTable.setColumnControlVisible(true); logTable.setModel(tableModel); logTable.setHorizontalScrollEnabled(true); logTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); operationFilter = new PatternFilter(".*", 0, 4); operationFilter.setAcceptNull(true); interfaceFilter = new PatternFilter(".*", 0, 3); interfaceFilter.setAcceptNull(true); targetHostFilter = new PatternFilter(".*", 0, 2); targetHostFilter.setAcceptNull(true); requestHostFilter = new PatternFilter(".*", 0, 1); requestHostFilter.setAcceptNull(true); Filter[] filters = new Filter[] { requestHostFilter, targetHostFilter, interfaceFilter, operationFilter }; FilterPipeline pipeline = new FilterPipeline(filters); logTable.setFilters(pipeline); ListSelectionModel sel = logTable.getSelectionModel(); sel.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent event) { int row = logTable.getSelectedRow(); if (row == -1) { // requestXmlDocument.setXml( null ); // responseXmlDocument.setXml( null ); requestModelItem.setMessageExchange(null); } else { WsdlMonitorMessageExchange exchange = tableModel.getMessageExchangeAt(row); requestModelItem.setMessageExchange(exchange); // responseModelItem.setMessageExchange( exchange ); // requestXmlDocument.setXml( exchange.getRequestContent() ); // responseXmlDocument.setXml( exchange.getResponseContent() ); } addToMockServiceButton.setEnabled(row != -1); addToTestCaseButton.setEnabled(row != -1); // addToRestTestCaseButton.setEnabled( row != -1 ); createRequestButton.setEnabled(row != -1); } }); JPanel tablePane = new JPanel(); tablePane.setLayout(new BorderLayout()); toolbar.addGlue(); tablePane.add(buildFilterBar(), BorderLayout.NORTH); tablePane.add(new JScrollPane(logTable), BorderLayout.CENTER); return tablePane; } private JPanel buildFilterBar() { requestFilterModel = new DefaultComboBoxModel(new String[] { ALL_FILTER_OPTION }); targetHostFilterModel = new DefaultComboBoxModel(new String[] { ALL_FILTER_OPTION }); Dimension comboBoxSize = new Dimension(90, 18); requestHostFilterCombo = UISupport.setFixedSize(new JComboBox(requestFilterModel), comboBoxSize); // toolbar.addFixed( new JLabel( "<html><b>Filter:</b></html>")); // toolbar.addUnrelatedGap(); ButtonBarBuilder toolbar = new ButtonBarBuilder(); toolbar.addFixed(new JLabel("Request Host")); toolbar.addRelatedGap(); toolbar.addFixed(requestHostFilterCombo); toolbar.addUnrelatedGap(); requestHostFilterCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { int ix = requestHostFilterCombo.getSelectedIndex(); if (ix == -1) return; requestHostFilter.setAcceptNull(ix == 0); if (ix == 0) requestHostFilter.setPattern(".*", 0); else requestHostFilter.setPattern(requestHostFilterCombo.getSelectedItem().toString(), 0); updateRowCountLabel(); } }); toolbar.addFixed(new JLabel("Target Host")); toolbar.addRelatedGap(); targetHostFilterCombo = UISupport.setFixedSize(new JComboBox(targetHostFilterModel), comboBoxSize); toolbar.addFixed(targetHostFilterCombo); toolbar.addUnrelatedGap(); targetHostFilterCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { int ix = targetHostFilterCombo.getSelectedIndex(); if (ix == -1) return; targetHostFilter.setAcceptNull(ix == 0); if (ix == 0) targetHostFilter.setPattern(".*", 0); else targetHostFilter.setPattern(targetHostFilterCombo.getSelectedItem().toString(), 0); updateRowCountLabel(); } }); String[] interfaceNames = ModelSupport.getNames(new String[] { ALL_FILTER_OPTION }, ModelSupport.getChildren(getProject(), WsdlInterface.class)); toolbar.addFixed(new JLabel("Interface")); toolbar.addRelatedGap(); interfaceFilterCombo = UISupport.setFixedSize(new JComboBox(interfaceNames), comboBoxSize); toolbar.addFixed(interfaceFilterCombo); toolbar.addUnrelatedGap(); operationFilterModel = new DefaultComboBoxModel(new String[] { ALL_FILTER_OPTION }); interfaceFilterCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { String item = (String) interfaceFilterCombo.getSelectedItem(); operationFilterModel.removeAllElements(); if (item == null || getProject().getInterfaceByName(item) == null) { operationFilterModel.addElement(ALL_FILTER_OPTION); interfaceFilter.setPattern(".*", 0); } else if (getProject().getInterfaceByName(item) != null) { WsdlInterface iface = (WsdlInterface) getProject().getInterfaceByName(item); String[] operationNames = ModelSupport.getNames(new String[] { ALL_FILTER_OPTION }, iface.getOperationList()); for (String s : operationNames) operationFilterModel.addElement(s); interfaceFilter.setPattern(iface.getName(), 0); } } }); toolbar.addFixed(new JLabel("Operation")); toolbar.addRelatedGap(); operationFilterCombo = UISupport.setFixedSize(new JComboBox(operationFilterModel), comboBoxSize); toolbar.addFixed(operationFilterCombo); operationFilterCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { int ix = operationFilterCombo.getSelectedIndex(); if (ix == -1) { operationFilter.setPattern(".*", 0); updateRowCountLabel(); return; } operationFilter.setAcceptNull(ix == 0); if (ix == 0) operationFilter.setPattern(".*", 0); else operationFilter.setPattern(operationFilterCombo.getSelectedItem().toString(), 0); updateRowCountLabel(); } }); toolbar.setBorder(BorderFactory.createEmptyBorder(3, 2, 3, 0)); return toolbar.getPanel(); } protected void updateRowCountLabel() { rowCountLabel.setText(logTable.getRowCount() + "/" + tableModel.getRowCount() + " entries"); } private JComponent buildViewer() { requestModelItem = new MessageExchangeModelItem("monitor message exchange", null) { @Override public boolean hasRawData() { return true; } }; requestViewer = new MessageExchangeRequestMessageEditor(requestModelItem); responseViewer = new MessageExchangeResponseMessageEditor(requestModelItem); return UISupport.createHorizontalSplit(requestViewer, responseViewer); } private JComponent buildToolbars(JXToolBar mainToolbar) { toolbar = UISupport.createSmallToolbar(); mainToolbar.addFixed( startButton = UISupport.createToolbarButton(UISupport.createImageIcon("/run_testcase.gif"))); mainToolbar.addFixed( stopButton = UISupport.createToolbarButton(UISupport.createImageIcon("/stop_testcase.gif"))); mainToolbar.addFixed(optionsButton = UISupport.createToolbarButton(new SoapMonitorOptionsAction())); toolbar.addFixed( createRequestButton = UISupport.createToolbarButton(UISupport.createImageIcon("/request.gif"))); toolbar.addFixed( addToTestCaseButton = UISupport.createToolbarButton(UISupport.createImageIcon("/testCase.gif"))); // toolbar.addFixed( addToRestTestCaseButton = // UISupport.createToolbarButton( UISupport // .createImageIcon( "/testCase.gif" ) ) ); toolbar.addFixed(addToMockServiceButton = UISupport .createToolbarButton(UISupport.createImageIcon("/mockService.gif"))); toolbar.addFixed( clearButton = UISupport.createToolbarButton(UISupport.createImageIcon("/clear_loadtest.gif"))); startButton.setToolTipText("Starts the HTTP Monitor as configured"); stopButton.setToolTipText("Stops the HTTP Monitor"); optionsButton.setToolTipText("Sets Monitor Options"); clearButton.setToolTipText("Clear all/selected messages from the log"); createRequestButton.setToolTipText("Creates requests from selected messages"); addToTestCaseButton.setToolTipText("Adds selected requests to a TestCase"); // addToRestTestCaseButton.setToolTipText( // "Adds selected REST requests to a TestCase" ); addToMockServiceButton.setToolTipText("Adds selected reponses to a MockService"); createRequestButton.setEnabled(false); addToMockServiceButton.setEnabled(false); addToTestCaseButton.setEnabled(false); // addToRestTestCaseButton.setEnabled( false ); startButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { start(); } }); stopButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { stop(); } }); clearButton.addActionListener(new ClearAction()); createRequestButton.addActionListener(new CreateRequestsAction()); addToTestCaseButton.addActionListener(new AddToTestCaseAction()); // addToRestTestCaseButton.addActionListener( new // AddToRESTTestCaseAction() ); addToMockServiceButton.addActionListener(new AddToMockServiceAction()); mainToolbar.addGlue(); infoLabel = new JLabel(); infoLabel.setPreferredSize(new Dimension(150, 20)); infoLabel.setOpaque(false); mainToolbar.addFixed(infoLabel); progressBar = new JProgressBar(); JPanel progressBarPanel = UISupport.createProgressBarPanel(progressBar, 2, false); progressBarPanel.setPreferredSize(new Dimension(60, 20)); mainToolbar.addFixed(progressBarPanel); return toolbar; } /** * Method start */ public void start() { int localPort = getLocalPort(); // monitorEngine = new TcpMonMonitorEngine(); monitorEngine = new SoapMonitorEngineImpl(); ((SoapMonitorEngineImpl) monitorEngine).setSslEndpoint(sslEndpoint); monitorEngine.start(this, localPort); if (monitorEngine.isRunning()) { stopButton.setEnabled(true); startButton.setEnabled(false); optionsButton.setEnabled(false); infoLabel.setText((monitorEngine.isProxy() ? "HTTP Proxy " : "SSL Tunnel ") + "on port " + localPort); progressBar.setIndeterminate(true); if (setAsProxy) { oldProxyHost = SoapUI.getSettings().getString(ProxySettings.HOST, ""); oldProxyPort = SoapUI.getSettings().getString(ProxySettings.PORT, ""); oldProxyEnabled = SoapUI.getSettings().getBoolean(ProxySettings.ENABLE_PROXY); SoapUI.getSettings().setString(ProxySettings.HOST, "127.0.0.1"); SoapUI.getSettings().setString(ProxySettings.PORT, String.valueOf(localPort)); SoapUI.getSettings().setBoolean(ProxySettings.ENABLE_PROXY, true); SoapUI.setProxyEnabled(true); JToggleButton applyProxyButton = (JToggleButton) SoapUI.getApplyProxyButton(); if (applyProxyButton != null) applyProxyButton.setIcon(UISupport.createImageIcon(SoapUI.PROXY_ENABLED_ICON)); } SoapUI.log.info("Started HTTP Monitor on local port " + localPort); } else { stopButton.setEnabled(false); startButton.setEnabled(true); optionsButton.setEnabled(true); infoLabel.setText("Stopped"); progressBar.setIndeterminate(false); SoapUI.log.info("Could not start HTTP Monitor on local port " + localPort); } } /** * Method close */ public void close() { stop(); } /** * Method stop */ public void stop() { monitorEngine.stop(); if (addedEndpoints != null) { for (Interface iface : addedEndpoints.keySet()) iface.removeEndpoint(addedEndpoints.get(iface)); addedEndpoints.clear(); } stopButton.setEnabled(false); startButton.setEnabled(true); optionsButton.setEnabled(true); progressBar.setIndeterminate(false); infoLabel.setText("Stopped"); if (setAsProxy) { SoapUI.getSettings().setString(ProxySettings.HOST, oldProxyHost); SoapUI.getSettings().setString(ProxySettings.PORT, oldProxyPort); SoapUI.getSettings().setBoolean(ProxySettings.ENABLE_PROXY, oldProxyEnabled); SoapUI.setProxyEnabled(oldProxyEnabled); JToggleButton applyProxyButton = (JToggleButton) SoapUI.getApplyProxyButton(); if (applyProxyButton != null) { if (oldProxyEnabled) { applyProxyButton.setIcon(UISupport.createImageIcon(SoapUI.PROXY_ENABLED_ICON)); } else { applyProxyButton.setIcon(UISupport.createImageIcon(SoapUI.PROXY_DISABLED_ICON)); } } } } @AForm(description = "Set options for adding selected requests to a MockService", name = "Add To MockService") private final class AddToMockServiceAction implements ActionListener { private static final String CREATE_NEW_OPTION = "<Create New>"; private XFormDialog dialog; @AField(name = "Target MockService", description = "The target TestSuite", type = AFieldType.ENUMERATION) public final static String MOCKSERVICE = "Target MockService"; @AField(name = "Open Editor", description = "Open the created MockService", type = AFieldType.BOOLEAN) public final static String OPENEDITOR = "Open Editor"; public void actionPerformed(ActionEvent e) { int[] rows = logTable.getSelectedRows(); if (rows.length == 0) return; if (dialog == null) { dialog = ADialogBuilder.buildDialog(this.getClass()); } String[] testSuiteNames = ModelSupport.getNames(new String[] { CREATE_NEW_OPTION }, getProject().getMockServiceList()); dialog.setOptions(MOCKSERVICE, testSuiteNames); if (dialog.show()) { int withoutOperation = 0; for (int row : rows) { WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt(row); if (me.getOperation() == null) withoutOperation++; } if (withoutOperation == rows.length) { UISupport.showInfoMessage("No SOAP requests selected!"); return; } String targetMockServiceName = dialog.getValue(MOCKSERVICE); WsdlMockService mockService = getProject().getMockServiceByName(targetMockServiceName); if (mockService == null) { targetMockServiceName = ModelSupport.promptForUniqueName("MockService", getProject(), ""); if (targetMockServiceName == null) return; mockService = getProject().addNewMockService(targetMockServiceName); mockService.setIncomingWss(incomingResponseWss); } int cnt = 0; for (int row : rows) { WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt(row); if (me.getOperation() == null) continue; WsdlMockOperation mockOperation = mockService.getMockOperation(me.getOperation()); if (mockOperation == null) mockOperation = mockService.addNewMockOperation(me.getOperation()); WsdlMockResponse mockResponse = mockOperation.addNewMockResponse("Monitor Response " + (++cnt), false); mockResponse.setResponseContent(me.getResponseContent()); Attachment[] requestAttachments = me.getResponseAttachments(); if (requestAttachments != null) { for (Attachment attachment : requestAttachments) { mockResponse.addAttachment(attachment); } } } if (cnt == 0) { UISupport.showInfoMessage("No response messages found"); } else { UISupport.showInfoMessage("Added " + cnt + " MockResponses to MockService"); if (dialog.getBooleanValue(OPENEDITOR)) UISupport.selectAndShow(mockService); } } } } @AForm(description = "Set options for adding selected requests to a TestCase", name = "Add To TestCase") private final class AddToTestCaseAction implements ActionListener { private static final String CREATE_NEW_OPTION = "<Create New>"; private XFormDialog dialog; @AField(name = "Target TestSuite", description = "The target TestSuite", type = AFieldType.ENUMERATION) public final static String TESTSUITE = "Target TestSuite"; @AField(name = "Target TestCase", description = "The target TestCase for the requests", type = AFieldType.ENUMERATION) public final static String TESTCASE = "Target TestCase"; @AField(name = "Open Editor", description = "Open the created TestCase", type = AFieldType.BOOLEAN) public final static String OPENEDITOR = "Open Editor"; TestSuite testSuite; public void actionPerformed(ActionEvent e) { int[] rows = logTable.getSelectedRows(); if (rows.length == 0) return; if (dialog == null) { dialog = ADialogBuilder.buildDialog(this.getClass()); dialog.getFormField(TESTSUITE).addFormFieldListener(new XFormFieldListener() { public void valueChanged(XFormField sourceField, String newValue, String oldValue) { if (newValue.equals(CREATE_NEW_OPTION)) { dialog.setOptions(TESTCASE, new String[] { CREATE_NEW_OPTION }); } else { testSuite = getProject().getTestSuiteByName(newValue); dialog.setOptions(TESTCASE, testSuite == null ? new String[] { CREATE_NEW_OPTION } : ModelSupport.getNames(testSuite.getTestCaseList(), new String[] { CREATE_NEW_OPTION })); } } }); } String[] testSuiteNames = ModelSupport.getNames(new String[] { CREATE_NEW_OPTION }, getProject().getTestSuiteList()); dialog.setOptions(TESTSUITE, testSuiteNames); testSuite = getProject().getTestSuiteByName(dialog.getValue(TESTSUITE)); dialog.setOptions(TESTCASE, testSuite == null ? new String[] { CREATE_NEW_OPTION } : ModelSupport.getNames(testSuite.getTestCaseList(), new String[] { CREATE_NEW_OPTION })); if (dialog.show()) { String targetTestSuiteName = dialog.getValue(TESTSUITE); String targetTestCaseName = dialog.getValue(TESTCASE); WsdlTestSuite testSuite = getProject().getTestSuiteByName(targetTestSuiteName); if (testSuite == null) { targetTestSuiteName = ModelSupport.promptForUniqueName("TestSuite", getProject(), ""); if (targetTestSuiteName == null) return; testSuite = getProject().addNewTestSuite(targetTestSuiteName); } WsdlTestCase testCase = testSuite.getTestCaseByName(targetTestCaseName); if (testCase == null) { targetTestCaseName = ModelSupport.promptForUniqueName("TestCase", testSuite, ""); if (targetTestCaseName == null) return; testCase = testSuite.addNewTestCase(targetTestCaseName); } for (int row : rows) { WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt(row); if (me.getOperation() != null) { WsdlTestRequestStep test = (WsdlTestRequestStep) testCase .insertTestStep(WsdlTestRequestStepFactory.createConfig(me.getOperation(), "Monitor Request " + (row + 1)), -1); WsdlTestRequest request = test.getTestRequest(); request.setRequestContent(me.getRequestContent()); request.setEndpoint(me.getTargetUrl().toString()); request.setIncomingWss(incomingRequestWss); Attachment[] requestAttachments = me.getRequestAttachments(); if (requestAttachments != null) { for (Attachment attachment : requestAttachments) { request.importAttachment(attachment); } } } else { // if( me.getResponseContentType().contains( "/x-amf" ) ) // { // AMFRequestStepFactory httpRequestStepFactory = new // AMFRequestStepFactory(); // AMFRequestTestStep test = ( AMFRequestTestStep // )testCase.insertTestStep( httpRequestStepFactory // .createConfig( me, "Monitor Request " + ( row + 1 ) ), -1 // ); // // AMFRequest request = test.getAMFRequest(); // // request.setRequestContent( me.getRequestContent() ); // request.setEndpoint( me.getTargetUrl().toString() ); // request.setHttpHeaders( me.getRequestHeaders() ); // // } // else // { HttpRequestStepFactory httpRequestStepFactory = new HttpRequestStepFactory(); HttpTestRequestStep test = (HttpTestRequestStep) testCase.insertTestStep( httpRequestStepFactory.createConfig(me, "Monitor Request " + (row + 1)), -1); test.getTestRequest().setRequestHeaders(excludeHeaders(me.getRequestHeaders())); HttpTestRequest request = (HttpTestRequest) test.getHttpRequest(); request.setEndpoint(me.getTargetUrl().toString()); // request.setIncomingWss( incomingRequestWss ); String existingMediaType = me.getResponseHeaders().get("Content-Type", ""); if (!StringUtils.isNullOrEmpty(existingMediaType)) { request.setMediaType(existingMediaType); } if ("application/octet-stream".equals(existingMediaType) || "application/x-amf".equals(existingMediaType)) { request.attachBinaryData(me.getRequestContent().getBytes(), existingMediaType); } else { request.setRequestContent(me.getRequestContent()); test.getTestRequest().setRequestContent(me.getRequestContent()); } Attachment[] requestAttachments = me.getRequestAttachments(); if (requestAttachments != null) { for (Attachment attachment : requestAttachments) { request.importAttachment(attachment); } } // } } } if (dialog.getBooleanValue(OPENEDITOR)) UISupport.selectAndShow(testCase); } } } // @AForm( description = // "Set options for adding selected REST requests to a TestCase", name = // "Add Rest Test Step(s) To TestCase" ) // // private final class AddToRESTTestCaseAction implements ActionListener // { // private static final String CREATE_NEW_OPTION = "<Create New>"; // private XFormDialog dialog; // // @AField( name = "Target TestSuite", description = "The target TestSuite", // type = AFieldType.ENUMERATION ) // public final static String TESTSUITE = "Target TestSuite"; // // @AField( name = "Target TestCase", description = // "The target TestCase for the requests", type = AFieldType.ENUMERATION ) // public final static String TESTCASE = "Target TestCase"; // // @AField( name = "Open Editor", description = "Open the created TestCase", // type = AFieldType.BOOLEAN ) // public final static String OPENEDITOR = "Open Editor"; // // TestSuite testSuite; // // public void actionPerformed( ActionEvent e ) // { // int[] rows = logTable.getSelectedRows(); // if( rows.length == 0 ) // return; // // if( dialog == null ) // { // dialog = ADialogBuilder.buildDialog( this.getClass() ); // dialog.getFormField( TESTSUITE ).addFormFieldListener( new // XFormFieldListener() // { // public void valueChanged( XFormField sourceField, String newValue, String // oldValue ) // { // if( newValue.equals( CREATE_NEW_OPTION ) ) // { // dialog.setOptions( TESTCASE, new String[] { CREATE_NEW_OPTION } ); // } // else // { // testSuite = getProject().getTestSuiteByName( newValue ); // dialog.setOptions( TESTCASE, testSuite == null ? new String[] { // CREATE_NEW_OPTION } : ModelSupport // .getNames( testSuite.getTestCaseList(), new String[] { CREATE_NEW_OPTION } // ) ); // } // } // } ); // } // // String[] testSuiteNames = ModelSupport.getNames( new String[] { // CREATE_NEW_OPTION }, getProject() // .getTestSuiteList() ); // dialog.setOptions( TESTSUITE, testSuiteNames ); // testSuite = getProject().getTestSuiteByName( dialog.getValue( TESTSUITE ) // ); // dialog.setOptions( TESTCASE, testSuite == null ? new String[] { // CREATE_NEW_OPTION } : ModelSupport.getNames( // testSuite.getTestCaseList(), new String[] { CREATE_NEW_OPTION } ) ); // // if( dialog.show() ) // { // String targetTestSuiteName = dialog.getValue( TESTSUITE ); // String targetTestCaseName = dialog.getValue( TESTCASE ); // // WsdlTestSuite testSuite = getProject().getTestSuiteByName( // targetTestSuiteName ); // if( testSuite == null ) // { // targetTestSuiteName = ModelSupport.promptForUniqueName( "TestSuite", // getProject(), "" ); // if( targetTestSuiteName == null ) // return; // // testSuite = getProject().addNewTestSuite( targetTestSuiteName ); // } // // WsdlTestCase testCase = testSuite.getTestCaseByName( targetTestCaseName ); // if( testCase == null ) // { // targetTestCaseName = ModelSupport.promptForUniqueName( "TestCase", // testSuite, "" ); // if( targetTestCaseName == null ) // return; // // testCase = testSuite.addNewTestCase( targetTestCaseName ); // } // // for( int row : rows ) // { // WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt( row ); // // RestService restService = ( RestService )project.addNewInterface( // "Monitor Interface " + ( row + 1 ), // RestServiceFactory.REST_TYPE ); // restService.addEndpoint( me.getTargetUrl().getProtocol() // +"://"+me.getTargetUrl().getHost() ); // restService.setBasePath( me.getTargetUrl().getPath() ); // ( ( NewRestResourceActionBase )SoapUI.getActionRegistry().getAction( // NewRestResourceAction.SOAPUI_ACTION_ID ) ).performAutomatic( restService, // me.getTargetUrl() ); // // RestRequestStepFactory restRequestStepFactory = new // RestRequestStepFactory(); // RestTestRequestStep test = ( RestTestRequestStep )testCase.insertTestStep( // restRequestStepFactory // .createNewTestStep( testCase, "Monitor Request " + ( row + 1 ) ), -1 ); // test.getTestRequest().setRequestContent( me.getRequestContent() ); // test.getTestRequest().setRequestHeaders( me.getRequestHeaders() ); // // RestTestRequest request = ( RestTestRequest )test.getHttpRequest(); // request.setRequestContent( me.getRequestContent() ); // request.setEndpoint( me.getTargetUrl().toString() ); // // Attachment[] requestAttachments = me.getRequestAttachments(); // if( requestAttachments != null ) // { // for( Attachment attachment : requestAttachments ) // { // request.importAttachment( attachment ); // } // } // } // // if( dialog.getBooleanValue( OPENEDITOR ) ) // UISupport.selectAndShow( testCase ); // } // } // } private final class CreateRequestsAction implements ActionListener { public void actionPerformed(ActionEvent e) { int[] rows = logTable.getSelectedRows(); if (rows.length == 0) return; if (UISupport.confirm("Create " + rows.length + " requests", "Create Request")) { int withoutOperation = 0; for (int row : rows) { WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt(row); if (me.getOperation() == null) { withoutOperation++; continue; } WsdlRequest request = me.getOperation().addNewRequest("Monitor Request " + (row + 1)); request.setRequestContent(me.getRequestContent()); request.setEndpoint(me.getTargetUrl().toString()); Attachment[] requestAttachments = me.getRequestAttachments(); if (requestAttachments != null) { for (Attachment attachment : requestAttachments) { request.importAttachment(attachment); } } } if (withoutOperation > 0) { UISupport.showInfoMessage("For " + withoutOperation + "request(s) there are no operations", "Create Request"); } } } } private final class ClearAction implements ActionListener { public void actionPerformed(ActionEvent e) { if (logTable.getRowCount() == 0) return; int[] rows = logTable.getSelectedRows(); if (rows.length == 0) { if (UISupport.confirm("Clear monitor log?", "Clear Log")) tableModel.clear(); } else if (UISupport.confirm("Clear " + rows.length + " rows from monitor log?", "Clear Log")) { tableModel.clearRows(rows); } } } @SuppressWarnings("unchecked") public class MonitorLogTableModel extends AbstractTableModel { private List<WsdlMonitorMessageExchange> exchanges = new TreeList(); public MonitorLogTableModel() { } public synchronized void clear() { int sz = exchanges.size(); while (exchanges.size() > 0) { WsdlMonitorMessageExchange removed = exchanges.remove(0); removed.discard(); } fireTableRowsDeleted(0, sz); while (requestFilterModel.getSize() > 1) requestFilterModel.removeElementAt(1); while (targetHostFilterModel.getSize() > 1) targetHostFilterModel.removeElementAt(1); updateRowCountLabel(); } public synchronized void clearRows(int[] indices) { for (int c = indices.length; c > 0; c--) { int index = indices[c - 1]; WsdlMonitorMessageExchange removed = exchanges.remove(logTable.convertRowIndexToModel(index)); removed.discard(); fireTableRowsDeleted(index, index); updateRowCountLabel(); } } public int getColumnCount() { return 12; } public WsdlMonitorMessageExchange getMessageExchangeAt(int tableRow) { return exchanges.get(logTable.convertRowIndexToModel(tableRow)); } @Override public String getColumnName(int column) { switch (column) { case 0: return "Count."; case 1: return "Time"; case 2: return "Request Host"; case 3: return "Target Host"; case 4: return "Interface"; case 5: return "Operation"; case 6: return "Time Taken"; case 7: return "Req Sz"; case 8: return "Resp Sz"; case 9: return "Method"; case 10: return "Path"; case 11: return "Content-Type"; } return null; } public int getRowCount() { return exchanges.size(); } public Object getValueAt(int rowIndex, int columnIndex) { if (rowIndex < 0 || rowIndex >= exchanges.size()) return null; WsdlMonitorMessageExchange exchange = exchanges.get(rowIndex); if (exchange == null) return null; switch (columnIndex) { case 0: return rowIndex; case 1: return DateUtil.formatFull(new Date(exchange.getTimestamp())); case 2: return exchange.getRequestHost(); case 3: return exchange.getTargetUrl().getHost(); case 4: return exchange.getOperation() == null ? "- unknown -" : exchange.getOperation().getInterface().getName(); case 5: return exchange.getOperation() == null ? "- unknown -" : exchange.getOperation().getName(); case 6: return String.valueOf(exchange.getTimeTaken()); case 7: return String.valueOf(exchange.getRequestContentLength()); case 8: return String.valueOf(exchange.getResponseContentLength()); case 9: return String.valueOf(exchange.getRequestMethod()); case 10: return exchange.getTargetUrl().getPath(); case 11: return String.valueOf(exchange.getResponseContentType()); } return null; } public synchronized void addMessageExchange(WsdlMonitorMessageExchange exchange) { exchanges.add(exchange); int size = exchanges.size(); fireTableRowsInserted(size - 1, size); fitSizeToMaxRows(); String requestHost = exchange.getRequestHost(); if (requestFilterModel.getIndexOf(requestHost) == -1) { requestFilterModel.addElement(requestHost); } String host = exchange.getTargetUrl().getHost(); if (targetHostFilterModel.getIndexOf(host) == -1) { targetHostFilterModel.addElement(host); } updateRowCountLabel(); } public void fitSizeToMaxRows() { int removeCnt = 0; while (exchanges.size() > maxRows) { WsdlMonitorMessageExchange removed = exchanges.remove(0); removed.discard(); removeCnt++; } if (removeCnt > 0) { fireTableDataChanged(); updateRowCountLabel(); } } } protected String getHttpProxyHost() { return httpProxyHost; } /** * excludes proxy headers as well as headers set for excluding in Global * Preferences/WebRecordingSettings.EXCLUDED_HEADERS * * @param requestHeaders * @return */ private StringToStringsMap excludeHeaders(StringToStringsMap requestHeaders) { StringToStringsMap stsmap = new StringToStringsMap(); for (String key : requestHeaders.getKeys()) { if (!(key.contains("Proxy") || key.contains("Content")) && !BrowserComponent.isHeaderExcluded(key)) { stsmap.add(key, requestHeaders.get(key, "")); } } return stsmap; } protected void setHttpProxyHost(String proxyHost) { httpProxyHost = proxyHost; } protected int getHttpProxyPort() { return httpProxyPort; } protected void setHttpProxyPort(int proxyPort) { httpProxyPort = proxyPort; } // protected SlowLinkSimulator getSlowLink() // { // return slowLink; // } public String getTargetHost() { String host = targetEndpoint; try { URL url = new URL(host); return url.getHost(); } catch (MalformedURLException e) { return host; } } public String getTargetEndpoint() { return targetEndpoint; } public int getTargetPort() { try { URL url = new URL(targetEndpoint); return url.getPort() == -1 ? 80 : url.getPort(); } catch (MalformedURLException e) { return 80; } } public int getLocalPort() { return listenPort; } public synchronized void addMessageExchange(WsdlMonitorMessageExchange messageExchange) { messageExchangeStack.push(messageExchange); if (!stackProcessor.isRunning()) new Thread(stackProcessor, "SoapMonitor StackProcessor for project [" + getProject().getName() + "]") .start(); } private class StackProcessor implements Runnable { private boolean canceled; private boolean running; public void run() { running = true; SoapUI.log.info("Started stackprocessor for soapmonitor in project [" + getProject().getName() + "]"); while (!canceled && messageExchangeStack.size() > 0) { WsdlMonitorMessageExchange messageExchange = messageExchangeStack.pop(); if (messageExchange != null) { processMessage(messageExchange); } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } running = false; } private synchronized void processMessage(WsdlMonitorMessageExchange messageExchange) { messageExchange.prepare(project.getWssContainer().getIncomingWssByName(incomingRequestWss), project.getWssContainer().getIncomingWssByName(incomingResponseWss)); tableModel.addMessageExchange(messageExchange); fireOnMessageExchange(messageExchange); } @SuppressWarnings("unused") public void cancel() { canceled = true; } @SuppressWarnings("unused") protected boolean isCanceled() { return canceled; } protected boolean isRunning() { return running; } } public MonitorLogTableModel getLogModel() { return tableModel; } public void addSoapMonitorListener(MonitorListener listener) { listeners.add(listener); } public void removeSoapMonitorListener(MonitorListener listener) { listeners.remove(listener); } public WsdlProject getProject() { return project; } public class SoapMonitorOptionsAction extends AbstractAction { public SoapMonitorOptionsAction() { putValue(SMALL_ICON, UISupport.createImageIcon("/options.gif")); } public void actionPerformed(ActionEvent e) { if (optionsDialog == null) { optionsDialog = ADialogBuilder.buildDialog(OptionsForm.class); } StringList endpoints = new StringList(); endpoints.add(null); for (WsdlInterface iface : ModelSupport.getChildren(getProject(), WsdlInterface.class)) { endpoints.addAll(iface.getEndpoints()); } optionsDialog.setIntValue(OptionsForm.PORT, listenPort); optionsDialog.setIntValue(OptionsForm.MAXROWS, maxRows); optionsDialog.setOptions(OptionsForm.REQUEST_WSS, StringUtils.merge(project.getWssContainer().getIncomingWssNames(), "<none>")); optionsDialog.setOptions(OptionsForm.RESPONSE_WSS, StringUtils.merge(project.getWssContainer().getIncomingWssNames(), "<none>")); optionsDialog.setValue(OptionsForm.REQUEST_WSS, incomingRequestWss); optionsDialog.setValue(OptionsForm.RESPONSE_WSS, incomingResponseWss); optionsDialog.setValue(LaunchForm.SET_CONTENT_TYPES, project.getSettings() .getString(LaunchForm.SET_CONTENT_TYPES, SoapMonitorAction.defaultContentTypes())); if (optionsDialog.show()) { Settings settings = getProject().getSettings(); settings.setLong(OptionsForm.PORT, listenPort = optionsDialog.getIntValue(OptionsForm.PORT, listenPort)); settings.setLong(OptionsForm.MAXROWS, maxRows = optionsDialog.getIntValue(OptionsForm.MAXROWS, maxRows)); settings.setString(LaunchForm.SET_CONTENT_TYPES, optionsDialog.getValue(LaunchForm.SET_CONTENT_TYPES)); incomingRequestWss = optionsDialog.getValue(OptionsForm.REQUEST_WSS); incomingResponseWss = optionsDialog.getValue(OptionsForm.RESPONSE_WSS); tableModel.fitSizeToMaxRows(); } } @AForm(name = "HTTP Monitor Options", description = "Set options for HTTP Monitor", helpUrl = HelpUrls.SOAPMONITOR_HELP_URL, icon = UISupport.OPTIONS_ICON_PATH) private class OptionsForm { @AField(description = "The local port to listen on", name = "Port", type = AFieldType.INT) public final static String PORT = "Port"; @AField(description = "The maximum number of exchanges to log", name = "Max Log", type = AFieldType.INT) public final static String MAXROWS = "Max Log"; @AField(description = "The Incoming WSS configuration to use for processing requests", name = "Incoming Request WSS", type = AFieldType.ENUMERATION) public final static String REQUEST_WSS = "Incoming Request WSS"; @AField(description = "The Outgoing WSS configuration to use for processing responses", name = "Incoming Response WSS", type = AFieldType.ENUMERATION) public final static String RESPONSE_WSS = "Incoming Response WSS"; @AField(description = "Content types to monitor", name = "Content types to monitor", type = AFieldType.STRINGAREA) public final static String SET_CONTENT_TYPES = "Content types to monitor"; } } public void release() { requestViewer.release(); responseViewer.release(); if (optionsDialog != null) { optionsDialog.release(); optionsDialog = null; } inspectorPanel.release(); } public boolean isRunning() { return monitorEngine.isRunning(); } public void fireOnMessageExchange(WsdlMonitorMessageExchange messageExchange) { for (MonitorListener listener : listeners.get()) { try { listener.onMessageExchange(messageExchange); } catch (Throwable t) { SoapUI.logError(t); } } } public void fireOnRequest(ServletRequest request, ServletResponse response) { for (MonitorListener listener : listeners.get()) { try { listener.onRequest(this, request, response); } catch (Throwable t) { SoapUI.logError(t); } } } public void fireBeforeProxy(ServletRequest request, ServletResponse response, HttpRequest httpRequest) { for (MonitorListener listener : listeners.get()) { try { listener.beforeProxy(this, request, response, httpRequest); } catch (Throwable t) { SoapUI.logError(t); } } } public void fireAfterProxy(ServletRequest request, ServletResponse response, HttpRequest httpRequest, WsdlMonitorMessageExchange capturedData) { for (MonitorListener listener : listeners.get()) { try { listener.afterProxy(this, request, response, httpRequest, capturedData); } catch (Throwable t) { SoapUI.logError(t); } } } public static class SoapUIListenerSupport<T extends Object> { private Set<T> listeners = new HashSet<T>(); @SuppressWarnings("unused") private final Class<T> listenerClass; public SoapUIListenerSupport(Class<T> listenerClass) { this.listenerClass = listenerClass; listeners.addAll(SoapUI.getListenerRegistry().getListeners(listenerClass)); } public void add(T listener) { listeners.add(listener); } public void remove(T listener) { listeners.remove(listener); } public Collection<T> get() { return listeners; } } public MessageExchangeModelItem getRequestModelItem() { return requestModelItem; } }