001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.teststeps;
014:
015: import java.beans.PropertyChangeEvent;
016: import java.beans.PropertyChangeListener;
017: import java.util.ArrayList;
018: import java.util.Collection;
019:
020: import javax.swing.ImageIcon;
021:
022: import org.apache.log4j.Logger;
023:
024: import com.eviware.soapui.config.CallConfig;
025: import com.eviware.soapui.config.RequestStepConfig;
026: import com.eviware.soapui.config.TestStepConfig;
027: import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
028: import com.eviware.soapui.impl.wsdl.WsdlInterface;
029: import com.eviware.soapui.impl.wsdl.WsdlOperation;
030: import com.eviware.soapui.impl.wsdl.WsdlRequest;
031: import com.eviware.soapui.impl.wsdl.WsdlSubmit;
032: import com.eviware.soapui.impl.wsdl.submit.filters.PropertyExpansionRequestFilter;
033: import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
034: import com.eviware.soapui.impl.wsdl.support.assertions.Assertable.AssertionStatus;
035: import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
036: import com.eviware.soapui.impl.wsdl.teststeps.assertions.AssertionError;
037: import com.eviware.soapui.model.iface.Interface;
038: import com.eviware.soapui.model.iface.Operation;
039: import com.eviware.soapui.model.iface.Submit;
040: import com.eviware.soapui.model.iface.Request.SubmitException;
041: import com.eviware.soapui.model.project.Project;
042: import com.eviware.soapui.model.support.InterfaceListenerAdapter;
043: import com.eviware.soapui.model.support.ProjectListenerAdapter;
044: import com.eviware.soapui.model.support.TestStepBeanProperty;
045: import com.eviware.soapui.model.testsuite.TestRunContext;
046: import com.eviware.soapui.model.testsuite.TestRunner;
047: import com.eviware.soapui.model.testsuite.TestStepResult;
048: import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
049:
050: /**
051: * WsdlTestStep that executes a WsdlTestRequest
052: *
053: * @author Ole.Matzura
054: */
055:
056: public class WsdlTestRequestStep extends WsdlTestStep implements
057: PropertyChangeListener {
058: private final static Logger log = Logger
059: .getLogger(WsdlTestRequestStep.class);
060: private RequestStepConfig requestStepConfig;
061: private WsdlTestRequest testRequest;
062: private WsdlOperation wsdlOperation;
063: private final InternalProjectListener projectListener = new InternalProjectListener();
064: private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
065: private WsdlSubmit submit;
066:
067: public WsdlTestRequestStep(WsdlTestCase testCase,
068: TestStepConfig config, boolean forLoadTest) {
069: super (testCase, config, true, forLoadTest);
070:
071: if (getConfig().getConfig() != null) {
072: requestStepConfig = (RequestStepConfig) getConfig()
073: .getConfig().changeType(RequestStepConfig.type);
074:
075: wsdlOperation = findWsdlOperation();
076: if (wsdlOperation == null) {
077: log.error("Could not find operation ["
078: + requestStepConfig.getOperation()
079: + "] in interface ["
080: + requestStepConfig.getInterface()
081: + "] for test request");
082: requestStepConfig.setRequest(null);
083: } else {
084: if (!forLoadTest) {
085: wsdlOperation.getInterface().getProject()
086: .addProjectListener(projectListener);
087: wsdlOperation.getInterface().addInterfaceListener(
088: interfaceListener);
089:
090: // we need to listen for name changes which happen when interfaces are updated..
091: wsdlOperation.getInterface()
092: .addPropertyChangeListener(this );
093: wsdlOperation.addPropertyChangeListener(this );
094: }
095:
096: testRequest = new WsdlTestRequest(wsdlOperation,
097: requestStepConfig.getRequest(), this ,
098: forLoadTest);
099: testRequest.addPropertyChangeListener(this );
100:
101: if (config.isSetName())
102: testRequest.setName(config.getName());
103: else
104: config.setName(testRequest.getName());
105: }
106: } else {
107: requestStepConfig = (RequestStepConfig) getConfig()
108: .addNewConfig().changeType(RequestStepConfig.type);
109: }
110:
111: // init properties
112: addProperty(new TestStepBeanProperty("Endpoint", false,
113: testRequest, "endpoint", this ));
114: addProperty(new TestStepBeanProperty("Username", false,
115: testRequest, "username", this ));
116: addProperty(new TestStepBeanProperty("Password", false,
117: testRequest, "password", this ));
118: addProperty(new TestStepBeanProperty("Domain", false,
119: testRequest, "domain", this ));
120: addProperty(new TestStepBeanProperty("Request", false,
121: testRequest, "requestContent", this ));
122: addProperty(new TestStepBeanProperty("Response", true,
123: testRequest, "responseContent", this ));
124: }
125:
126: public WsdlTestRequestStep(WsdlTestCase testCase,
127: TestStepConfig testStep, WsdlRequest request) {
128: this (testCase, testStep, false);
129:
130: requestStepConfig.setInterface(request.getOperation()
131: .getInterface().getName());
132: requestStepConfig
133: .setOperation(request.getOperation().getName());
134:
135: CallConfig testRequestConfig = requestStepConfig.getRequest();
136: if (testRequestConfig == null)
137: testRequestConfig = requestStepConfig.addNewRequest();
138:
139: testRequestConfig.setName(request.getName());
140: testRequestConfig.setEncoding(request.getEncoding());
141: testRequestConfig.setEndpoint(request.getEndpoint());
142: testRequestConfig.addNewRequest().setStringValue(
143: request.getRequestContent());
144: if (request.getConfig().getCredentials() != null)
145: testRequestConfig.setCredentials(request.getConfig()
146: .getCredentials());
147:
148: testRequest = new WsdlTestRequest(request.getOperation(),
149: testRequestConfig, this , false);
150: request.copyAttachmentsTo(testRequest);
151:
152: testRequest.addPropertyChangeListener(this );
153:
154: wsdlOperation = findWsdlOperation();
155: if (wsdlOperation == null)
156: throw new RuntimeException("Failed to find operation ["
157: + requestStepConfig.getOperation()
158: + "] for test request");
159:
160: wsdlOperation.getInterface().addInterfaceListener(
161: interfaceListener);
162: wsdlOperation.getInterface().getProject().addProjectListener(
163: projectListener);
164: }
165:
166: public WsdlTestRequestStep(WsdlTestCase testCase,
167: WsdlTestRequest sourceRequest) {
168: this (testCase, TestStepConfig.Factory.newInstance(),
169: sourceRequest);
170: }
171:
172: public WsdlTestStep clone(WsdlTestCase targetTestCase, String name) {
173: onSave();
174:
175: TestStepConfig config = (TestStepConfig) getConfig().copy();
176: RequestStepConfig stepConfig = (RequestStepConfig) config
177: .getConfig().changeType(RequestStepConfig.type);
178:
179: while (stepConfig.getRequest().sizeOfAttachmentArray() > 0)
180: stepConfig.getRequest().removeAttachment(0);
181:
182: config.setName(name);
183: stepConfig.getRequest().setName(name);
184:
185: WsdlTestRequestStep result = (WsdlTestRequestStep) targetTestCase
186: .addTestStep(config);
187: testRequest.copyAttachmentsTo(result.getTestRequest());
188:
189: return result;
190: }
191:
192: private WsdlOperation findWsdlOperation() {
193: WsdlTestCase testCase = (WsdlTestCase) getTestCase();
194: if (testCase == null || testCase.getTestSuite() == null)
195: return null;
196:
197: Project project = testCase.getTestSuite().getProject();
198: WsdlOperation operation = null;
199: for (int c = 0; c < project.getInterfaceCount(); c++) {
200: if (project.getInterfaceAt(c).getName().equals(
201: requestStepConfig.getInterface())) {
202: WsdlInterface iface = (WsdlInterface) project
203: .getInterfaceAt(c);
204: for (int i = 0; i < iface.getOperationCount(); i++) {
205: if (iface.getOperationAt(i).getName().equals(
206: requestStepConfig.getOperation())) {
207: operation = (WsdlOperation) iface
208: .getOperationAt(i);
209: break;
210: }
211: }
212:
213: if (operation != null)
214: break;
215: }
216: }
217: return operation;
218: }
219:
220: public String getInterfaceName() {
221: return requestStepConfig.getInterface();
222: }
223:
224: public String getOperationName() {
225: return requestStepConfig.getOperation();
226: }
227:
228: public void release() {
229: super .release();
230:
231: if (wsdlOperation == null)
232: wsdlOperation = findWsdlOperation();
233:
234: if (wsdlOperation != null) {
235: wsdlOperation.removePropertyChangeListener(this );
236: wsdlOperation.getInterface().getProject()
237: .removeProjectListener(projectListener);
238: wsdlOperation.getInterface().removeInterfaceListener(
239: interfaceListener);
240: wsdlOperation.getInterface().removePropertyChangeListener(
241: this );
242: }
243:
244: testRequest.removePropertyChangeListener(this );
245: testRequest.release();
246: }
247:
248: public void resetConfigOnMove(TestStepConfig config) {
249: super .resetConfigOnMove(config);
250:
251: requestStepConfig = (RequestStepConfig) config.getConfig()
252: .changeType(RequestStepConfig.type);
253: testRequest.updateConfig(requestStepConfig.getRequest());
254: }
255:
256: public ImageIcon getIcon() {
257: return testRequest.getIcon();
258: }
259:
260: public String getName() {
261: return testRequest == null ? super .getName() : testRequest
262: .getName();
263: }
264:
265: public WsdlTestRequest getTestRequest() {
266: return testRequest;
267: }
268:
269: public void setName(String name) {
270: testRequest.setName(name);
271: super .setName(name);
272: }
273:
274: public void propertyChange(PropertyChangeEvent arg0) {
275: if (arg0.getSource() == wsdlOperation) {
276: if (arg0.getPropertyName().equals(Operation.NAME_PROPERTY)) {
277: requestStepConfig.setOperation((String) arg0
278: .getNewValue());
279: }
280: } else if (arg0.getSource() == wsdlOperation.getInterface()) {
281: if (arg0.getPropertyName().equals(Interface.NAME_PROPERTY)) {
282: requestStepConfig.setInterface((String) arg0
283: .getNewValue());
284: }
285: } else {
286: notifyPropertyChanged(arg0.getPropertyName(), arg0
287: .getOldValue(), arg0.getNewValue());
288: }
289: }
290:
291: public TestStepResult run(TestRunner runner,
292: TestRunContext runContext) {
293: WsdlTestRequestStepResult testStepResult = new WsdlTestRequestStepResult(
294: this );
295:
296: try {
297: submit = testRequest.submit(runContext, false);
298: WsdlResponse response = (WsdlResponse) submit.getResponse();
299:
300: if (submit.getStatus() != Submit.Status.CANCELED) {
301: if (submit.getStatus() == Submit.Status.ERROR) {
302: testStepResult.setStatus(TestStepStatus.FAILED);
303: testStepResult.addMessage(submit.getError()
304: .toString());
305:
306: testRequest.setResponse(null, runContext);
307: } else if (response == null) {
308: testStepResult.setStatus(TestStepStatus.FAILED);
309: testStepResult
310: .addMessage("Request is missing response");
311:
312: testRequest.setResponse(null, runContext);
313: } else {
314: testRequest.setResponse(response, runContext);
315:
316: testStepResult
317: .setTimeTaken(response.getTimeTaken());
318: testStepResult.setSize(response.getContentLength());
319: testStepResult.setResponse(response);
320:
321: switch (testRequest.getAssertionStatus()) {
322: case FAILED:
323: testStepResult.setStatus(TestStepStatus.FAILED);
324: break;
325: case VALID:
326: testStepResult.setStatus(TestStepStatus.OK);
327: break;
328: case UNKNOWN:
329: testStepResult
330: .setStatus(TestStepStatus.UNKNOWN);
331: break;
332: }
333: }
334: } else {
335: testStepResult.setStatus(TestStepStatus.CANCELED);
336: testStepResult.addMessage("Request was canceled");
337: }
338:
339: if (response != null)
340: testStepResult.setRequestContent(response
341: .getRequestContent());
342: else
343: testStepResult.setRequestContent(testRequest
344: .getRequestContent());
345: } catch (SubmitException e) {
346: testStepResult.setStatus(TestStepStatus.FAILED);
347: testStepResult.addMessage("SubmitException: " + e);
348: } finally {
349: submit = null;
350: }
351:
352: testStepResult.setDomain(testRequest.getDomain());
353: testStepResult.setUsername(testRequest.getUsername());
354: testStepResult.setPassword(testRequest.getPassword());
355: testStepResult
356: .setEndpoint(PropertyExpansionRequestFilter
357: .expandProperties(runContext, testRequest
358: .getEndpoint()));
359: testStepResult.setEncoding(testRequest.getEncoding());
360:
361: if (testStepResult.getStatus() != TestStepStatus.CANCELED) {
362: AssertionStatus assertionStatus = testRequest
363: .getAssertionStatus();
364: switch (assertionStatus) {
365: case FAILED: {
366: testStepResult.setStatus(TestStepStatus.FAILED);
367: if (getAssertionCount() == 0) {
368: testStepResult.addMessage("Invalid/empty response");
369: } else
370: for (int c = 0; c < getAssertionCount(); c++) {
371: AssertionError[] errors = getAssertionAt(c)
372: .getErrors();
373: if (errors != null) {
374: for (AssertionError error : errors) {
375: testStepResult.addMessage(error
376: .getMessage());
377: }
378: }
379: }
380:
381: break;
382: }
383: // default : testStepResult.setStatus( TestStepStatus.OK ); break;
384: }
385: }
386:
387: return testStepResult;
388: }
389:
390: public WsdlMessageAssertion getAssertionAt(int index) {
391: return testRequest.getAssertionAt(index);
392: }
393:
394: public int getAssertionCount() {
395: return testRequest.getAssertionCount();
396: }
397:
398: public class InternalProjectListener extends ProjectListenerAdapter {
399: public void interfaceRemoved(Interface iface) {
400: if (wsdlOperation != null
401: && wsdlOperation.getInterface().equals(iface)) {
402: log
403: .debug("Removing test step due to removed interface");
404: ((WsdlTestCase) getTestCase())
405: .removeTestStep(WsdlTestRequestStep.this );
406: }
407: }
408: }
409:
410: public class InternalInterfaceListener extends
411: InterfaceListenerAdapter {
412: @Override
413: public void operationRemoved(Operation operation) {
414: if (operation == wsdlOperation) {
415: log
416: .debug("Removing test step due to removed operation");
417: ((WsdlTestCase) getTestCase())
418: .removeTestStep(WsdlTestRequestStep.this );
419: }
420: }
421:
422: @Override
423: public void operationUpdated(Operation operation) {
424: if (operation == wsdlOperation) {
425: requestStepConfig.setOperation(operation.getName());
426: }
427: }
428: }
429:
430: public boolean cancel() {
431: if (submit == null)
432: return false;
433:
434: submit.cancel();
435:
436: return true;
437: }
438:
439: @Override
440: public Collection<WsdlInterface> getRequiredInterfaces() {
441: ArrayList<WsdlInterface> result = new ArrayList<WsdlInterface>();
442: result.add(findWsdlOperation().getInterface());
443: return result;
444: }
445:
446: public boolean dependsOn(AbstractWsdlModelItem modelItem) {
447: if (modelItem instanceof Interface
448: && testRequest.getOperation().getInterface() == modelItem) {
449: return true;
450: } else if (modelItem instanceof Operation
451: && testRequest.getOperation() == modelItem) {
452: return true;
453: }
454:
455: return false;
456: }
457:
458: @Override
459: public void onSave() {
460: testRequest.onSave();
461: }
462:
463: public String getDescription() {
464: return testRequest.getDescription();
465: }
466:
467: public void setDescription(String description) {
468: testRequest.setDescription(description);
469: }
470:
471: public void setOperation(WsdlOperation operation) {
472: if (wsdlOperation == operation)
473: return;
474:
475: WsdlOperation oldOperation = wsdlOperation;
476: wsdlOperation = operation;
477: requestStepConfig.setInterface(operation.getInterface()
478: .getName());
479: requestStepConfig.setOperation(operation.getName());
480:
481: oldOperation.removePropertyChangeListener(this);
482: wsdlOperation.addPropertyChangeListener(this);
483:
484: testRequest.setOperation(wsdlOperation);
485: }
486: }
|