/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl.teststeps;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.MockOperationDispatchStyleConfig;
import com.eviware.soapui.config.MockResponseConfig;
import com.eviware.soapui.config.MockResponseStepConfig;
import com.eviware.soapui.config.MockServiceConfig;
import com.eviware.soapui.config.TestAssertionConfig;
import com.eviware.soapui.config.TestStepConfig;
import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse.ResponseHeaderHolder;
import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner;
import com.eviware.soapui.impl.wsdl.mock.dispatch.QueryMatchMockOperationDispatcher;
import com.eviware.soapui.impl.wsdl.panels.mockoperation.WsdlMockResultMessageExchange;
import com.eviware.soapui.impl.wsdl.support.IconAnimator;
import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry;
import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.iface.Interface;
import com.eviware.soapui.model.iface.Operation;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.mock.MockResult;
import com.eviware.soapui.model.mock.MockRunner;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
import com.eviware.soapui.model.support.DefaultTestStepProperty;
import com.eviware.soapui.model.support.InterfaceListenerAdapter;
import com.eviware.soapui.model.support.MockRunListenerAdapter;
import com.eviware.soapui.model.support.ModelSupport;
import com.eviware.soapui.model.support.ProjectListenerAdapter;
import com.eviware.soapui.model.support.TestRunListenerAdapter;
import com.eviware.soapui.model.support.TestStepBeanProperty;
import com.eviware.soapui.model.testsuite.Assertable;
import com.eviware.soapui.model.testsuite.AssertedXPath;
import com.eviware.soapui.model.testsuite.AssertionError;
import com.eviware.soapui.model.testsuite.AssertionsListener;
import com.eviware.soapui.model.testsuite.LoadTestRunner;
import com.eviware.soapui.model.testsuite.OperationTestStep;
import com.eviware.soapui.model.testsuite.RequestAssertedMessageExchange;
import com.eviware.soapui.model.testsuite.TestAssertion;
import com.eviware.soapui.model.testsuite.TestCaseRunContext;
import com.eviware.soapui.model.testsuite.TestCaseRunner;
import com.eviware.soapui.model.testsuite.TestStep;
import com.eviware.soapui.model.testsuite.TestStepResult;
import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
import com.eviware.soapui.monitor.TestMonitor;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.resolver.ChangeOperationResolver;
import com.eviware.soapui.support.resolver.ImportInterfaceResolver;
import com.eviware.soapui.support.resolver.RemoveTestStepResolver;
import com.eviware.soapui.support.resolver.ResolveContext;
import com.eviware.soapui.support.resolver.ResolveContext.PathToResolve;
import com.eviware.soapui.support.types.StringToStringsMap;
import org.apache.log4j.Logger;
import javax.swing.ImageIcon;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WsdlMockResponseTestStep extends WsdlTestStepWithProperties implements OperationTestStep,
PropertyChangeListener, Assertable, PropertyExpansionContainer {
private final static Logger log = Logger.getLogger(WsdlMockResponseTestStep.class);
public static final String STATUS_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@status";
public static final String TIMEOUT_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@timeout";
private MockResponseStepConfig mockResponseStepConfig;
private MockResponseConfig mockResponseConfig;
private WsdlMockOperation mockOperation;
private WsdlTestMockService mockService;
private WsdlMockRunner mockRunner;
private WsdlMockResponse mockResponse;
private WsdlMockResult lastResult;
private AssertionsSupport assertionsSupport;
private InternalMockRunListener mockRunListener;
private StartStepMockRunListener startStepMockRunListener;
private final InternalProjectListener projectListener = new InternalProjectListener();
private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
private final InternalTestRunListener testRunListener = new InternalTestRunListener();
private WsdlInterface iface;
private AssertionStatus oldStatus;
private IconAnimator<WsdlMockResponseTestStep> iconAnimator;
private ImageIcon validRequestIcon;
private ImageIcon failedRequestIcon;
private ImageIcon disabledRequestIcon;
private ImageIcon unknownRequestIcon;
private WsdlMockResponse testMockResponse;
private WsdlTestStep startTestStep;
private boolean forLoadTest;
public WsdlMockResponseTestStep(WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest) {
super(testCase, config, true, forLoadTest);
if (config.getConfig() != null) {
mockResponseStepConfig = (MockResponseStepConfig) config.getConfig().changeType(MockResponseStepConfig.type);
mockResponseConfig = mockResponseStepConfig.getResponse();
} else {
mockResponseStepConfig = (MockResponseStepConfig) config.addNewConfig().changeType(
MockResponseStepConfig.type);
mockResponseConfig = mockResponseStepConfig.addNewResponse();
}
initAssertions();
initMockObjects(testCase);
this.forLoadTest = forLoadTest;
if (!forLoadTest) {
if (iface != null) {
iface.getProject().addProjectListener(projectListener);
iface.addInterfaceListener(interfaceListener);
}
iconAnimator = new IconAnimator<WsdlMockResponseTestStep>(this, "/mockResponseStep.gif",
"/exec_mockResponse.gif", 4);
initIcons();
}
// init properties
initProperties();
testCase.addTestRunListener(testRunListener);
testCase.addPropertyChangeListener(this);
}
@Override
public void afterLoad() {
super.afterLoad();
if (mockResponseStepConfig.isSetStartStep()) {
startTestStep = getTestCase().getTestStepByName(mockResponseStepConfig.getStartStep());
if (startTestStep != null) {
startTestStep.addPropertyChangeListener(this);
}
}
}
private void initProperties() {
if (mockResponse != null) {
addProperty(new TestStepBeanProperty("Response", false, mockResponse, "responseContent", this));
}
addProperty(new DefaultTestStepProperty("Request", true, new DefaultTestStepProperty.PropertyHandlerAdapter() {
public String getValue(DefaultTestStepProperty property) {
MockResult mockResult = mockResponse == null ? null : mockResponse.getMockResult();
return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
}
}, this));
}
@Override
public ImageIcon getIcon() {
if (forLoadTest || iconAnimator == null) {
return null;
}
TestMonitor testMonitor = SoapUI.getTestMonitor();
if (testMonitor != null
&& (testMonitor.hasRunningLoadTest(getTestCase()) || testMonitor.hasRunningSecurityTest(getTestCase()))) {
return disabledRequestIcon;
}
ImageIcon icon = iconAnimator.getIcon();
if (icon == iconAnimator.getBaseIcon()) {
AssertionStatus status = getAssertionStatus();
if (status == AssertionStatus.VALID) {
return validRequestIcon;
} else if (status == AssertionStatus.FAILED) {
return failedRequestIcon;
} else if (status == AssertionStatus.UNKNOWN) {
return unknownRequestIcon;
}
}
return icon;
}
public void initIcons() {
if (validRequestIcon == null) {
validRequestIcon = UISupport.createImageIcon("/valid_soap_request_step.png");
}
if (failedRequestIcon == null) {
failedRequestIcon = UISupport.createImageIcon("/invalid_soap_request_step.png");
}
if (unknownRequestIcon == null) {
unknownRequestIcon = UISupport.createImageIcon("/soap_request_step.png");
}
if (disabledRequestIcon == null) {
disabledRequestIcon = UISupport.createImageIcon("/disabled_request.gif");
}
}
private void initAssertions() {
assertionsSupport = new AssertionsSupport(this, new AssertableConfig() {
public TestAssertionConfig addNewAssertion() {
return mockResponseStepConfig.addNewAssertion();
}
public List<TestAssertionConfig> getAssertionList() {
return mockResponseStepConfig.getAssertionList();
}
public void removeAssertion(int ix) {
mockResponseStepConfig.removeAssertion(ix);
}
public TestAssertionConfig insertAssertion(TestAssertionConfig source, int ix) {
TestAssertionConfig conf = mockResponseStepConfig.insertNewAssertion(ix);
conf.set(source);
return conf;
}
});
}
private void initMockObjects(WsdlTestCase testCase) {
MockServiceConfig mockServiceConfig = MockServiceConfig.Factory.newInstance();
mockServiceConfig.setPath(mockResponseStepConfig.getPath());
mockServiceConfig.setPort(mockResponseStepConfig.getPort());
mockServiceConfig.setHost(mockResponseStepConfig.getHost());
mockService = new WsdlTestMockService(this, mockServiceConfig);
mockService.setName(getName());
iface = (WsdlInterface) testCase.getTestSuite().getProject()
.getInterfaceByName(mockResponseStepConfig.getInterface());
if (iface == null) {
} else {
iface.addInterfaceListener(interfaceListener);
mockOperation = (WsdlMockOperation) mockService.addNewMockOperation(iface.getOperationByName(mockResponseStepConfig
.getOperation()));
if (mockResponseStepConfig.getHandleFault()) {
mockService.setFaultMockOperation(mockOperation);
}
if (mockResponseStepConfig.getHandleResponse()) {
mockService.setDispatchResponseMessages(true);
}
mockResponse = mockOperation.addNewMockResponse("MockResponse", false);
mockResponse.setConfig(mockResponseConfig);
mockOperation.setDefaultResponse(mockResponse.getName());
mockResponse.addPropertyChangeListener(this);
mockResponse.getWsaConfig().addPropertyChangeListener(this);
}
}
public void resetConfigOnMove(TestStepConfig config) {
super.resetConfigOnMove(config);
mockResponseStepConfig = (MockResponseStepConfig) config.getConfig().changeType(MockResponseStepConfig.type);
mockResponseConfig = mockResponseStepConfig.getResponse();
mockResponse.setConfig(mockResponseConfig);
assertionsSupport.refresh();
}
@Override
public boolean cancel() {
if (mockRunner != null) {
mockRunner.stop();
mockRunner = null;
}
if (mockRunListener != null) {
mockRunListener.cancel();
}
return true;
}
@Override
public void prepare(TestCaseRunner testRunner, TestCaseRunContext testRunContext) throws Exception {
super.prepare(testRunner, testRunContext);
LoadTestRunner loadTestRunner = (LoadTestRunner) testRunContext
.getProperty(TestCaseRunContext.LOAD_TEST_RUNNER);
mockRunListener = new InternalMockRunListener();
for (TestAssertion assertion : getAssertionList()) {
assertion.prepare(testRunner, testRunContext);
}
if (loadTestRunner == null) {
mockService.addMockRunListener(mockRunListener);
// mockRunner = mockService.start( ( WsdlTestRunContext )testRunContext );
} else {
synchronized (STATUS_PROPERTY) {
mockRunner = (WsdlMockRunner) testRunContext.getProperty("sharedMockServiceRunner");
if (mockRunner == null) {
mockService.addMockRunListener(mockRunListener);
mockRunner = mockService.start((WsdlTestRunContext) testRunContext);
} else {
mockRunner.getMockContext().getMockService().addMockRunListener(mockRunListener);
}
}
}
if (startTestStep instanceof WsdlMockResponseTestStep) {
System.out.println("Adding StartStepMockRunListener from [" + getName() + "] to [" + startTestStep.getName()
+ "]");
startStepMockRunListener = new StartStepMockRunListener(testRunContext,
(WsdlMockResponseTestStep) startTestStep);
}
}
protected void initTestMockResponse(TestCaseRunContext testRunContext) {
if (StringUtils.hasContent(getQuery()) && StringUtils.hasContent(getMatch())) {
String name = "MockResponse" + Math.random();
testMockResponse = mockOperation.addNewMockResponse(name, false);
testMockResponse.setConfig((MockResponseConfig) mockResponse.getConfig().copy());
testMockResponse.setName(name);
QueryMatchMockOperationDispatcher dispatcher = (QueryMatchMockOperationDispatcher) mockOperation
.setDispatchStyle(MockOperationDispatchStyleConfig.QUERY_MATCH.toString());
for (QueryMatchMockOperationDispatcher.Query query : dispatcher.getQueries()) {
dispatcher.deleteQuery(query);
}
mockOperation.setDefaultResponse(null);
QueryMatchMockOperationDispatcher.Query query = dispatcher.addQuery("Match");
query.setQuery(PropertyExpander.expandProperties(testRunContext, getQuery()));
query.setMatch(PropertyExpander.expandProperties(testRunContext, getMatch()));
query.setResponse(testMockResponse.getName());
} else {
testMockResponse = mockResponse;
testMockResponse.setMockResult(null);
}
}
public TestStepResult run(TestCaseRunner testRunner, TestCaseRunContext context) {
LoadTestRunner loadTestRunner = (LoadTestRunner) context.getProperty(TestCaseRunContext.LOAD_TEST_RUNNER);
if (loadTestRunner == null) {
return internalRun((WsdlTestRunContext) context);
} else {
// block other threads during loadtesting -> this should be improved!
// synchronized( STATUS_PROPERTY )
{
if (loadTestRunner.getStatus() == LoadTestRunner.Status.RUNNING) {
return internalRun((WsdlTestRunContext) context);
} else {
WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult(this);
result.setStatus(TestStepStatus.UNKNOWN);
return result;
}
}
}
}
private TestStepResult internalRun(WsdlTestRunContext context) {
if (iconAnimator != null) {
iconAnimator.start();
}
WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult(this);
try {
this.lastResult = null;
mockResponse.setMockResult(null);
result.startTimer();
if (!mockRunListener.hasResult()) {
if (testMockResponse == null) {
initTestMockResponse(context);
}
if (mockRunner == null) {
mockRunner = mockService.start(context);
}
if (!mockRunner.isRunning()) {
mockRunner.start();
}
long timeout = getTimeout();
synchronized (mockRunListener) {
mockRunListener.waitForRequest(timeout);
}
}
result.stopTimer();
if (mockRunner != null && mockRunner.isRunning()) {
mockRunner.stop();
}
AssertedWsdlMockResultMessageExchange messageExchange = new AssertedWsdlMockResultMessageExchange(
mockRunListener.getLastResult());
result.setMessageExchange(messageExchange);
if (mockRunListener.getLastResult() != null) {
lastResult = mockRunListener.getLastResult();
mockResponse.setMockResult(lastResult);
context.setProperty(AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, messageExchange);
assertResult(lastResult, context);
}
if (mockRunListener.getLastResult() == null) {
if (mockRunListener.isCanceled()) {
result.setStatus(TestStepStatus.CANCELED);
} else {
result.setStatus(TestStepStatus.FAILED);
result.addMessage("Timeout occured after " + getTimeout() + " milliseconds");
}
} else {
AssertionStatus status = getAssertionStatus();
if (status == AssertionStatus.FAILED) {
result.setStatus(TestStepStatus.FAILED);
if (getAssertionCount() == 0) {
result.addMessage("Invalid/empty request");
} else {
for (int c = 0; c < getAssertionCount(); c++) {
WsdlMessageAssertion assertion = getAssertionAt(c);
AssertionError[] errors = assertion.getErrors();
if (errors != null) {
for (AssertionError error : errors) {
result.addMessage("[" + assertion.getName() + "] " + error.getMessage());
}
}
}
}
} else if (status == AssertionStatus.UNKNOWN) {
result.setStatus(TestStepStatus.UNKNOWN);
} else {
result.setStatus(TestStepStatus.OK);
}
mockRunListener.setLastResult(null);
}
} catch (Exception e) {
result.stopTimer();
result.setStatus(TestStepStatus.FAILED);
result.setError(e);
SoapUI.logError(e);
} finally {
if (iconAnimator != null) {
iconAnimator.stop();
}
}
return result;
}
private void assertResult(WsdlMockResult result, SubmitContext context) {
if (oldStatus == null) {
oldStatus = getAssertionStatus();
}
for (int c = 0; c < getAssertionCount(); c++) {
WsdlMessageAssertion assertion = getAssertionAt(c);
if (!assertion.isDisabled()) {
assertion.assertRequest(new WsdlMockResultMessageExchange(result, getMockResponse()), context);
}
}
AssertionStatus newStatus = getAssertionStatus();
if (newStatus != oldStatus) {
notifyPropertyChanged(STATUS_PROPERTY, oldStatus, newStatus);
oldStatus = newStatus;
}
}
@Override
public void finish(TestCaseRunner testRunner, TestCaseRunContext testRunContext) {
if (mockRunListener != null) {
if (mockRunListener.isWaiting()) {
mockRunListener.cancel();
}
mockService.removeMockRunListener(mockRunListener);
mockRunListener = null;
}
if (startStepMockRunListener != null) {
startStepMockRunListener.release();
startStepMockRunListener = null;
}
if (testMockResponse != null) {
if (testMockResponse != mockResponse) {
mockOperation.removeMockResponse(testMockResponse);
}
testMockResponse = null;
}
if (mockRunner != null) {
if (mockRunner.isRunning()) {
mockRunner.stop();
}
mockRunner = null;
}
}
public WsdlMockResult getLastResult() {
return lastResult;
}
public class InternalMockRunListener extends MockRunListenerAdapter {
private boolean canceled;
private boolean waiting;
private WsdlMockResult lastResult;
public synchronized void onMockResult(MockResult result) {
System.out.println("in onMockResult for [" + getName() + "] for result " + result.hashCode());
// is this for us?
if (this.lastResult == null && waiting && result.getMockResponse() == testMockResponse) {
waiting = false;
System.out.println("Got mockrequest to [" + getName() + "]");
// save
this.lastResult = (WsdlMockResult) result;
notifyPropertyChanged("lastResult", null, lastResult);
// stop runner -> NO, we can't stop, mockengine is still writing
// response..
// actually we have to - but this is not a problem if soapUI has been configured to leave the mockengine running
// in which case it won't terminate the connector during the response
mockRunner.stop();
// testMockResponse.setMockResult( null );
synchronized (this) {
notifyAll();
}
}
}
public void setLastResult(WsdlMockResult lastResult) {
this.lastResult = lastResult;
}
public void cancel() {
canceled = true;
if (waiting) {
synchronized (this) {
notifyAll();
}
}
// mockRunListener.onMockResult( null );
}
public WsdlMockResult getLastResult() {
return lastResult;
}
public boolean isCanceled() {
return canceled;
}
public boolean hasResult() {
return lastResult != null;
}
public boolean isWaiting() {
return waiting;
}
public void setWaiting(boolean waiting) {
this.waiting = waiting;
}
public void waitForRequest(long timeout) throws InterruptedException {
waiting = true;
wait(timeout);
}
@Override
public void onMockRunnerStart(MockRunner mockRunner) {
waiting = false;
lastResult = null;
canceled = false;
}
}
public WsdlMockResponse getMockResponse() {
return mockResponse;
}
public void setPort(int port) {
int old = getPort();
mockService.setPort(port);
mockResponseStepConfig.setPort(port);
notifyPropertyChanged("port", old, port);
}
public String getPath() {
return mockResponseStepConfig.getPath();
}
public String getHost() {
return mockResponseStepConfig.getHost();
}
public long getContentLength() {
return mockResponse == null ? 0 : mockResponse.getContentLength();
}
public int getPort() {
return mockResponseStepConfig.getPort();
}
public String getEncoding() {
return mockResponse.getEncoding();
}
public void setEncoding(String encoding) {
String old = getEncoding();
mockResponse.setEncoding(encoding);
notifyPropertyChanged("encoding", old, encoding);
}
public boolean isMtomEnabled() {
return mockResponse.isMtomEnabled();
}
public void setMtomEnabled(boolean enabled) {
if (isMtomEnabled() == enabled) {
return;
}
mockResponse.setMtomEnabled(enabled);
notifyPropertyChanged("mtomEnabled", !enabled, enabled);
}
public String getOutgoingWss() {
return mockResponse.getOutgoingWss();
}
public void setOutgoingWss(String outgoingWss) {
String old = getOutgoingWss();
mockResponse.setOutgoingWss(outgoingWss);
notifyPropertyChanged("outgoingWss", old, outgoingWss);
}
public void setQuery(String s) {
String old = getQuery();
mockResponseStepConfig.setQuery(s);
notifyPropertyChanged("query", old, s);
}
public String getQuery() {
return mockResponseStepConfig.getQuery();
}
public String getMatch() {
return mockResponseStepConfig.getMatch();
}
public void setMatch(String s) {
String old = getMatch();
mockResponseStepConfig.setMatch(s);
notifyPropertyChanged("match", old, s);
}
public String getStartStep() {
return startTestStep == null ? "" : startTestStep.getName();
}
public void setStartStep(String startStep) {
String old = getStartStep();
if (startTestStep != null) {
startTestStep.removePropertyChangeListener(this);
startTestStep = null;
}
if (startStep != null) {
startTestStep = getTestCase().getTestStepByName(startStep);
if (startTestStep != null) {
startTestStep.addPropertyChangeListener(this);
}
}
mockResponseStepConfig.setStartStep(startStep);
notifyPropertyChanged("startStep", old, startStep);
}
public boolean isRemoveEmptyContent() {
return mockResponse.isRemoveEmptyContent();
}
public boolean isStripWhitespaces() {
return mockResponse.isStripWhitespaces();
}
public void setRemoveEmptyContent(boolean removeEmptyContent) {
mockResponse.setRemoveEmptyContent(removeEmptyContent);
}
public void setStripWhitespaces(boolean stripWhitespaces) {
mockResponse.setStripWhitespaces(stripWhitespaces);
}
public void setPath(String path) {
mockService.setPath(path);
mockResponseStepConfig.setPath(path);
}
public void setHost(String host) {
mockService.setHost(host);
mockResponseStepConfig.setHost(host);
}
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getSource() == mockResponse || evt.getSource() == mockResponse.getWsaConfig()) {
if (!evt.getPropertyName().equals(WsdlMockResponse.ICON_PROPERTY)) {
mockResponse.beforeSave();
mockResponseConfig.set(mockResponse.getConfig());
}
notifyPropertyChanged(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
} else if (evt.getSource() == getTestCase() && evt.getPropertyName().equals("testSteps")
&& evt.getNewValue() == null && evt.getOldValue() == startTestStep && startTestStep != null) {
setStartStep(null);
} else if (evt.getSource() == startTestStep && evt.getPropertyName().equals(WsdlTestStep.NAME_PROPERTY)) {
mockResponseStepConfig.setStartStep(String.valueOf(evt.getNewValue()));
}
}
public WsdlMessageAssertion addAssertion(String assertionName) {
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
try {
TestAssertionConfig assertionConfig = mockResponseStepConfig.addNewAssertion();
assertionConfig.setType(TestAssertionRegistry.getInstance().getAssertionTypeForName(assertionName));
WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion(assertionConfig);
assertionsSupport.fireAssertionAdded(assertion);
if (getMockResponse().getMockResult() != null) {
WsdlMockResult mockResult = (WsdlMockResult) getMockResponse().getMockResult();
WsdlMockResultMessageExchange messageExchange
= new WsdlMockResultMessageExchange(mockResult, getMockResponse());
assertion.assertRequest(messageExchange, new WsdlSubmitContext(this));
notifier.notifyChange();
}
return assertion;
} catch (Exception e) {
SoapUI.logError(e);
return null;
}
}
public void addAssertionsListener(AssertionsListener listener) {
assertionsSupport.addAssertionsListener(listener);
}
public WsdlMessageAssertion getAssertionAt(int c) {
return assertionsSupport.getAssertionAt(c);
}
public int getAssertionCount() {
return assertionsSupport.getAssertionCount();
}
public void removeAssertionsListener(AssertionsListener listener) {
assertionsSupport.removeAssertionsListener(listener);
}
public AssertionStatus getAssertionStatus() {
AssertionStatus currentStatus = AssertionStatus.UNKNOWN;
int cnt = getAssertionCount();
if (cnt == 0) {
return currentStatus;
}
if (mockResponse.getMockResult() != null) {
if (mockResponse.getMockResult().getMockRequest() == null) {
currentStatus = AssertionStatus.FAILED;
}
} else {
return currentStatus;
}
for (int c = 0; c < cnt; c++) {
WsdlMessageAssertion assertion = getAssertionAt(c);
if (assertion.isDisabled()) {
continue;
}
if (assertion.getStatus() == AssertionStatus.FAILED) {
currentStatus = AssertionStatus.FAILED;
break;
}
}
if (currentStatus == AssertionStatus.UNKNOWN) {
currentStatus = AssertionStatus.VALID;
}
return currentStatus;
}
public void removeAssertion(TestAssertion assertion) {
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
try {
assertionsSupport.removeAssertion((WsdlMessageAssertion) assertion);
} finally {
((WsdlMessageAssertion) assertion).release();
notifier.notifyChange();
}
}
public TestAssertion moveAssertion(int ix, int offset) {
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
WsdlMessageAssertion assertion = getAssertionAt(ix);
try {
return assertionsSupport.moveAssertion(ix, offset);
} finally {
((WsdlMessageAssertion) assertion).release();
notifier.notifyChange();
}
}
public String getAssertableContentAsXml() {
return getAssertableContent();
}
public String getAssertableContent() {
MockResult mockResult = getMockResponse().getMockResult();
return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
}
public TestStep getTestStep() {
return this;
}
@Override
public void setName(String name) {
super.setName(name);
if (mockService != null) {
mockService.setName(getName());
}
}
public WsdlInterface getInterface() {
return getOperation().getInterface();
}
public WsdlOperation getOperation() {
return getMockResponse().getMockOperation().getOperation();
}
public void setInterface(String string) {
WsdlInterface iface = (WsdlInterface) getTestCase().getTestSuite().getProject().getInterfaceByName(string);
if (iface != null) {
mockResponseStepConfig.setInterface(iface.getName());
WsdlOperation operation = iface.getOperationAt(0);
mockResponseStepConfig.setOperation(operation.getName());
mockOperation.setOperation(operation);
}
}
public void setOperation(String string) {
WsdlOperation operation = getInterface().getOperationByName(string);
if (operation != null) {
mockResponseStepConfig.setOperation(string);
mockOperation.setOperation(operation);
}
}
private class PropertyChangeNotifier {
private AssertionStatus oldStatus;
private ImageIcon oldIcon;
public PropertyChangeNotifier() {
oldStatus = getAssertionStatus();
oldIcon = getIcon();
}
public void notifyChange() {
AssertionStatus newStatus = getAssertionStatus();
ImageIcon newIcon = getIcon();
if (oldStatus != newStatus) {
notifyPropertyChanged(STATUS_PROPERTY, oldStatus, newStatus);
}
if (oldIcon != newIcon) {
notifyPropertyChanged(ICON_PROPERTY, oldIcon, getIcon());
}
}
}
@Override
public void release() {
super.release();
assertionsSupport.release();
if (mockResponse != null) {
mockResponse.removePropertyChangeListener(this);
mockResponse.getWsaConfig().removePropertyChangeListener(this);
}
if (mockService != null) {
mockService.release();
}
if (iface != null) {
iface.getProject().removeProjectListener(projectListener);
iface.removeInterfaceListener(interfaceListener);
}
getTestCase().removeTestRunListener(testRunListener);
getTestCase().removePropertyChangeListener(this);
if (startTestStep != null) {
startTestStep.removePropertyChangeListener(this);
}
if (lastResult != null) {
lastResult = null;
}
}
public AssertableType getAssertableType() {
return AssertableType.REQUEST;
}
@Override
public Collection<Interface> getRequiredInterfaces() {
ArrayList<Interface> result = new ArrayList<Interface>();
result.add(getInterface());
return result;
}
public String getDefaultSourcePropertyName() {
return "Response";
}
public String getDefaultTargetPropertyName() {
return "Request";
}
@Override
public void beforeSave() {
super.beforeSave();
if (mockResponse != null) {
mockResponse.beforeSave();
mockResponseConfig.set(mockResponse.getConfig());
}
}
public long getTimeout() {
return mockResponseStepConfig.getTimeout();
}
public void setTimeout(long timeout) {
long old = getTimeout();
mockResponseStepConfig.setTimeout(timeout);
notifyPropertyChanged(TIMEOUT_PROPERTY, old, timeout);
}
@Override
public boolean dependsOn(AbstractWsdlModelItem<?> modelItem) {
return modelItem == getOperation().getInterface();
}
public class InternalProjectListener extends ProjectListenerAdapter {
public void interfaceRemoved(Interface iface) {
if (getOperation() != null && getOperation().getInterface().equals(iface)) {
log.debug("Removing test step due to removed interface");
(getTestCase()).removeTestStep(WsdlMockResponseTestStep.this);
}
}
}
public class InternalInterfaceListener extends InterfaceListenerAdapter {
public void operationRemoved(Operation operation) {
if (operation == getOperation()) {
log.debug("Removing test step due to removed operation");
(getTestCase()).removeTestStep(WsdlMockResponseTestStep.this);
}
}
@Override
public void operationUpdated(Operation operation) {
if (operation == getOperation()) {
setOperation(operation.getName());
}
}
}
public WsdlMessageAssertion cloneAssertion(TestAssertion source, String name) {
TestAssertionConfig conf = mockResponseStepConfig.addNewAssertion();
conf.set(((WsdlMessageAssertion) source).getConfig());
conf.setName(name);
WsdlMessageAssertion result = assertionsSupport.addWsdlAssertion(conf);
assertionsSupport.fireAssertionAdded(result);
return result;
}
public List<TestAssertion> getAssertionList() {
return new ArrayList<TestAssertion>(assertionsSupport.getAssertionList());
}
@Override
public List<? extends ModelItem> getChildren() {
return assertionsSupport.getAssertionList();
}
public PropertyExpansion[] getPropertyExpansions() {
List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
result.addAll(PropertyExpansionUtils.extractPropertyExpansions(this, mockResponse, "responseContent"));
StringToStringsMap responseHeaders = mockResponse.getResponseHeaders();
for (Map.Entry<String, List<String>> headerEntry : responseHeaders.entrySet()) {
for (String value : headerEntry.getValue()) {
result.addAll(PropertyExpansionUtils.extractPropertyExpansions(this,
new ResponseHeaderHolder(headerEntry.getKey(), value, mockResponse), "value"));
}
}
mockResponse.addWsaPropertyExpansions(result, mockResponse.getWsaConfig(), this);
return result.toArray(new PropertyExpansion[result.size()]);
}
public WsdlMessageAssertion getAssertionByName(String name) {
return assertionsSupport.getAssertionByName(name);
}
public Map<String, TestAssertion> getAssertions() {
Map<String, TestAssertion> result = new HashMap<String, TestAssertion>();
for (TestAssertion assertion : getAssertionList()) {
result.put(assertion.getName(), assertion);
}
return result;
}
private class AssertedWsdlMockResultMessageExchange extends WsdlMockResultMessageExchange implements
RequestAssertedMessageExchange, AssertedXPathsContainer {
private List<AssertedXPath> assertedXPaths;
public AssertedWsdlMockResultMessageExchange(WsdlMockResult mockResult) {
super(mockResult, mockResult == null ? null : (WsdlMockResponse) mockResult.getMockResponse());
}
public AssertedXPath[] getAssertedXPathsForRequest() {
return assertedXPaths == null ? new AssertedXPath[0] : assertedXPaths
.toArray(new AssertedXPath[assertedXPaths.size()]);
}
public void addAssertedXPath(AssertedXPath assertedXPath) {
if (assertedXPaths == null) {
assertedXPaths = new ArrayList<AssertedXPath>();
}
assertedXPaths.add(assertedXPath);
}
}
public String getDefaultAssertableContent() {
return getOperation().createRequest(true);
}
@Override
public void resolve(ResolveContext<?> context) {
super.resolve(context);
if (mockOperation == null) {
if (context.hasThisModelItem(this, "Missing Operation in Project", mockResponseStepConfig.getInterface()
+ "/" + mockResponseStepConfig.getOperation())) {
return;
}
context.addPathToResolve(this, "Missing Operation in Project",
mockResponseStepConfig.getInterface() + "/" + mockResponseStepConfig.getOperation()).addResolvers(
new RemoveTestStepResolver(this), new ImportInterfaceResolver(this) {
@Override
protected boolean update() {
initMockObjects(getTestCase());
initProperties();
setDisabled(false);
return true;
}
}, new ChangeOperationResolver(this, "Operation") {
@Override
public boolean update() {
WsdlOperation operation = (WsdlOperation) getSelectedOperation();
setInterface(operation.getInterface().getName());
setOperation(operation.getName());
initMockObjects(getTestCase());
initProperties();
setDisabled(false);
return true;
}
protected Interface[] getInterfaces(WsdlProject project) {
List<WsdlInterface> interfaces = ModelSupport.getChildren(project, WsdlInterface.class);
return interfaces.toArray(new Interface[interfaces.size()]);
}
}
);
} else {
mockOperation.resolve(context);
if (context.hasThisModelItem(this, "Missing Operation in Project", mockResponseStepConfig.getInterface()
+ "/" + mockResponseStepConfig.getOperation())) {
@SuppressWarnings("rawtypes")
//FIXME need to understand why this needs casting, we need to find the root cause
PathToResolve path = (PathToResolve) context.getPath(this, "Missing Operation in Project",
mockResponseStepConfig.getInterface() + "/" + mockResponseStepConfig.getOperation());
path.setSolved(true);
}
}
}
private void startListening(TestCaseRunContext runContext) throws Exception {
if (mockRunner == null) {
mockRunner = mockService.start((WsdlTestRunContext) runContext);
}
if (testMockResponse == null) {
initTestMockResponse(runContext);
} else if (!mockRunner.isRunning()) {
try {
mockRunner.start();
} catch (Exception e) {
SoapUI.logError(e);
}
}
if (mockRunListener != null) {
mockRunListener.setWaiting(true);
}
}
private class InternalTestRunListener extends TestRunListenerAdapter {
@Override
public void beforeStep(TestCaseRunner testRunner, TestCaseRunContext runContext, TestStep testStep) {
if (runContext.getCurrentStep() == startTestStep) {
if (startTestStep instanceof WsdlMockResponseTestStep) {
// do nothing - this is done in the StartStepMockRunListener instead
} else {
try {
startListening(runContext);
} catch (Exception e) {
SoapUI.logError(e);
}
}
}
}
}
private class StartStepMockRunListener implements PropertyChangeListener {
private TestCaseRunContext runContext;
private WsdlMockResponseTestStep wsdlMockResponseTestStep;
public StartStepMockRunListener(TestCaseRunContext runContext, WsdlMockResponseTestStep wsdlMockResponseTestStep) {
this.runContext = runContext;
this.wsdlMockResponseTestStep = wsdlMockResponseTestStep;
wsdlMockResponseTestStep.addPropertyChangeListener("lastResult", this);
}
public void release() {
wsdlMockResponseTestStep.removePropertyChangeListener("lastResult", this);
wsdlMockResponseTestStep = null;
runContext = null;
}
public void propertyChange(PropertyChangeEvent evt) {
try {
startListening(runContext);
} catch (Exception e) {
SoapUI.logError(e);
}
}
}
}