/*
* soapUI, copyright (C) 2004-2011 eviware.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.teststeps;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.ImageIcon;
import org.apache.log4j.Logger;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.JdbcRequestTestStepConfig;
import com.eviware.soapui.config.TestAssertionConfig;
import com.eviware.soapui.config.TestStepConfig;
import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
import com.eviware.soapui.impl.wsdl.panels.teststeps.JdbcRequest;
import com.eviware.soapui.impl.wsdl.panels.teststeps.JdbcResponse;
import com.eviware.soapui.impl.wsdl.panels.teststeps.JdbcSubmit;
import com.eviware.soapui.impl.wsdl.support.JdbcMessageExchange;
import com.eviware.soapui.impl.wsdl.support.XmlBeansPropertiesTestPropertyHolder;
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.AssertableType;
import com.eviware.soapui.model.iface.Interface;
import com.eviware.soapui.model.iface.Request.SubmitException;
import com.eviware.soapui.model.iface.Submit;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
import com.eviware.soapui.model.support.TestStepBeanProperty;
import com.eviware.soapui.model.testsuite.Assertable;
import com.eviware.soapui.model.testsuite.AssertionError;
import com.eviware.soapui.model.testsuite.AssertionsListener;
import com.eviware.soapui.model.testsuite.SamplerTestStep;
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.TestProperty;
import com.eviware.soapui.model.testsuite.TestPropertyListener;
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.support.StringUtils;
/**
* WsdlTestStep that executes a WsdlTestRequest
*
* @author dragica.soldo
*/
public class JdbcRequestTestStep extends WsdlTestStepWithProperties implements Assertable, MutableTestPropertyHolder,
PropertyChangeListener, SamplerTestStep
{
@SuppressWarnings( "unused" )
private final static Logger log = Logger.getLogger( WsdlTestRequestStep.class );
public final static String JDBCREQUEST = JdbcRequestTestStep.class.getName() + "@jdbcrequest";
public static final String STATUS_PROPERTY = WsdlTestRequest.class.getName() + "@status";
public static final String RESPONSE_PROPERTY = "response";
protected static final String DRIVER_FIELD = "Driver";
protected static final String CONNSTR_FIELD = "Connection String";
protected static final String PASS_FIELD = "Password";
public static final String PASS_TEMPLATE = "PASS_VALUE";
public static final String QUERY_FIELD = "SQL Query";
protected static final String STOREDPROCEDURE_FIELD = "Stored Procedure";
protected static final String DATA_CONNECTION_FIELD = "Connection";
protected static final String QUERY_ELEMENT = "query";
protected static final String STOREDPROCEDURE_ELEMENT = "stored-procedure";
private AssertionsSupport assertionsSupport;
private PropertyChangeNotifier notifier;
private XmlBeansPropertiesTestPropertyHolder propertyHolderSupport;
private JdbcRequestTestStepConfig jdbcRequestTestStepConfig;
private JdbcRequest jdbcRequest;
private JdbcSubmit submit;
public JdbcRequestTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
{
super( testCase, config, true, forLoadTest );
if( getConfig().getConfig() != null )
{
jdbcRequestTestStepConfig = ( JdbcRequestTestStepConfig )getConfig().getConfig().changeType(
JdbcRequestTestStepConfig.type );
}
else
{
jdbcRequestTestStepConfig = ( JdbcRequestTestStepConfig )getConfig().addNewConfig().changeType(
JdbcRequestTestStepConfig.type );
}
if( jdbcRequestTestStepConfig.getProperties() == null )
jdbcRequestTestStepConfig.addNewProperties();
jdbcRequest = new JdbcRequest( this, forLoadTest );
propertyHolderSupport = new XmlBeansPropertiesTestPropertyHolder( this, jdbcRequestTestStepConfig.getProperties() );
addResponseAsXmlVirtualProperty();
initAssertions();
}
private void addResponseAsXmlVirtualProperty()
{
TestStepBeanProperty responseProperty = new TestStepBeanProperty( WsdlTestStepWithProperties.RESPONSE_AS_XML,
false, this, "responseContent", this )
{
@Override
public String getDefaultValue()
{
return "";
}
};
propertyHolderSupport.addVirtualProperty( WsdlTestStepWithProperties.RESPONSE_AS_XML, responseProperty );
}
public JdbcRequestTestStepConfig getJdbcRequestTestStepConfig()
{
return jdbcRequestTestStepConfig;
}
public void resetConfigOnMove( TestStepConfig config )
{
super.resetConfigOnMove( config );
jdbcRequestTestStepConfig = ( JdbcRequestTestStepConfig )config.getConfig().changeType(
JdbcRequestTestStepConfig.type );
propertyHolderSupport.resetPropertiesConfig( jdbcRequestTestStepConfig.getProperties() );
// addResponseAsXmlVirtualProperty();
assertionsSupport.refresh();
}
@Override
public WsdlTestStep clone( WsdlTestCase targetTestCase, String name )
{
beforeSave();
TestStepConfig config = ( TestStepConfig )getConfig().copy();
JdbcRequestTestStep result = ( JdbcRequestTestStep )targetTestCase.addTestStep( config );
return result;
}
@Override
public void release()
{
super.release();
}
public TestStepResult run( TestCaseRunner runner, TestCaseRunContext runContext )
{
JdbcTestStepResult testStepResult = new JdbcTestStepResult( this );
testStepResult.startTimer();
runContext.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, testStepResult );
try
{
submit = jdbcRequest.submit( runContext, false );
JdbcResponse response = submit.getResponse();
if( submit.getStatus() != Submit.Status.CANCELED )
{
if( submit.getStatus() == Submit.Status.ERROR )
{
testStepResult.setStatus( TestStepStatus.FAILED );
testStepResult.addMessage( submit.getError().toString() );
jdbcRequest.setResponse( null );
}
else if( response == null )
{
testStepResult.setStatus( TestStepStatus.FAILED );
testStepResult.addMessage( "Request is missing response" );
jdbcRequest.setResponse( null );
}
else
{
runContext.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, testStepResult );
jdbcRequest.setResponse( response );
testStepResult.setTimeTaken( response.getTimeTaken() );
testStepResult.setSize( response.getContentLength() );
switch( jdbcRequest.getAssertionStatus() )
{
case FAILED :
testStepResult.setStatus( TestStepStatus.FAILED );
break;
case VALID :
testStepResult.setStatus( TestStepStatus.OK );
break;
case UNKNOWN :
testStepResult.setStatus( TestStepStatus.UNKNOWN );
break;
}
testStepResult.setResponse( response, testStepResult.getStatus() != TestStepStatus.FAILED );
}
}
else
{
testStepResult.setStatus( TestStepStatus.CANCELED );
testStepResult.addMessage( "Request was canceled" );
}
if( response != null )
testStepResult.setRequestContent( response.getRequestContent() );
else
testStepResult.setRequestContent( jdbcRequest.getRequestContent() );
testStepResult.stopTimer();
}
catch( SubmitException e )
{
testStepResult.setStatus( TestStepStatus.FAILED );
testStepResult.addMessage( "SubmitException: " + e );
testStepResult.stopTimer();
}
finally
{
submit = null;
}
if( testStepResult.getStatus() != TestStepStatus.CANCELED )
{
assertResponse( runContext );
AssertionStatus assertionStatus = jdbcRequest.getAssertionStatus();
switch( assertionStatus )
{
case FAILED :
{
testStepResult.setStatus( TestStepStatus.FAILED );
if( getAssertionCount() == 0 )
{
testStepResult.addMessage( "Invalid/empty response" );
}
else
for( int c = 0; c < getAssertionCount(); c++ )
{
TestAssertion assertion = getAssertionAt( c );
AssertionError[] errors = assertion.getErrors();
if( errors != null )
{
for( AssertionError error : errors )
{
testStepResult.addMessage( "[" + assertion.getName() + "] " + error.getMessage() );
}
}
}
break;
}
// default : testStepResult.setStatus( TestStepStatus.OK ); break;
}
}
if( isDiscardResponse() && !SoapUI.getDesktop().hasDesktopPanel( this ) )
jdbcRequest.setResponse( null );
return testStepResult;
}
@Override
public boolean cancel()
{
if( submit == null )
return false;
submit.cancel();
return true;
}
public String getDefaultSourcePropertyName()
{
return "Response";
}
private void initAssertions()
{
assertionsSupport = new AssertionsSupport( this, new AssertableConfig()
{
public TestAssertionConfig addNewAssertion()
{
return getJdbcRequestTestStepConfig().addNewAssertion();
}
public List<TestAssertionConfig> getAssertionList()
{
return getJdbcRequestTestStepConfig().getAssertionList();
}
public void removeAssertion( int ix )
{
getJdbcRequestTestStepConfig().removeAssertion( ix );
}
public TestAssertionConfig insertAssertion( TestAssertionConfig source, int ix )
{
TestAssertionConfig conf = getJdbcRequestTestStepConfig().insertNewAssertion( ix );
conf.set( source );
return conf;
}
} );
}
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() );
oldStatus = newStatus;
oldIcon = newIcon;
}
}
public TestAssertion addAssertion( String assertionLabel )
{
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
try
{
WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionLabel );
if( assertion == null )
return null;
if( getJdbcRequest().getResponse() != null )
{
assertion.assertResponse( new JdbcMessageExchange( this, getJdbcRequest().getResponse() ),
new WsdlTestRunContext( this ) );
notifier.notifyChange();
}
return assertion;
}
catch( Exception e )
{
SoapUI.logError( e );
return null;
}
}
public void addAssertionsListener( AssertionsListener listener )
{
assertionsSupport.addAssertionsListener( listener );
}
public TestAssertion cloneAssertion( TestAssertion source, String name )
{
return assertionsSupport.cloneAssertion( source, name );
}
public String getAssertableContent()
{
return getJdbcRequest().getResponse() == null ? null : getJdbcRequest().getResponse().getContentAsString();
}
public String getResponseContent()
{
return getJdbcRequest().getResponse() == null ? "" : getJdbcRequest().getResponse().getContentAsString();
}
public WsdlMessageAssertion importAssertion( WsdlMessageAssertion source, boolean overwrite, boolean createCopy,
String newName )
{
return assertionsSupport.importAssertion( source, overwrite, createCopy, newName );
}
public AssertableType getAssertableType()
{
return AssertableType.RESPONSE;
}
public TestAssertion getAssertionAt( int c )
{
return assertionsSupport.getAssertionAt( c );
}
public TestAssertion getAssertionByName( String name )
{
return assertionsSupport.getAssertionByName( name );
}
public int getAssertionCount()
{
return assertionsSupport.getAssertionCount();
}
public List<TestAssertion> getAssertionList()
{
return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
}
public void propertyChange( PropertyChangeEvent arg0 )
{
if( arg0.getPropertyName().equals( TestAssertion.CONFIGURATION_PROPERTY )
|| arg0.getPropertyName().equals( TestAssertion.DISABLED_PROPERTY ) )
{
if( getJdbcRequest().getResponse() != null )
{
assertResponse( new WsdlTestRunContext( this ) );
}
}
}
public Map<String, TestAssertion> getAssertions()
{
return assertionsSupport.getAssertions();
}
public String getDefaultAssertableContent()
{
return null;
}
public AssertionStatus getAssertionStatus()
{
return jdbcRequest.getAssertionStatus();
}
public ImageIcon getIcon()
{
return jdbcRequest.getIcon();
}
public Interface getInterface()
{
return null;
}
public TestAssertion moveAssertion( int ix, int offset )
{
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
TestAssertion assertion = getAssertionAt( ix );
try
{
return assertionsSupport.moveAssertion( ix, offset );
}
finally
{
( ( WsdlMessageAssertion )assertion ).release();
notifier.notifyChange();
}
}
public void removeAssertion( TestAssertion assertion )
{
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
try
{
assertionsSupport.removeAssertion( ( WsdlMessageAssertion )assertion );
}
finally
{
( ( WsdlMessageAssertion )assertion ).release();
notifier.notifyChange();
}
}
public void removeAssertionsListener( AssertionsListener listener )
{
assertionsSupport.removeAssertionsListener( listener );
}
public void assertResponse( SubmitContext context )
{
try
{
if( notifier == null )
notifier = new PropertyChangeNotifier();
JdbcMessageExchange messageExchange = new JdbcMessageExchange( this, getJdbcRequest().getResponse() );
if( getJdbcRequest().getResponse() != null )
{
// assert!
for( WsdlMessageAssertion assertion : assertionsSupport.getAssertionList() )
{
assertion.assertResponse( messageExchange, context );
}
}
notifier.notifyChange();
}
catch( Exception e )
{
e.printStackTrace();
}
}
public TestProperty addProperty( String name )
{
return propertyHolderSupport.addProperty( name );
}
public TestProperty removeProperty( String propertyName )
{
return propertyHolderSupport.removeProperty( propertyName );
}
public void removeAllProperties()
{
for( String propertyName : propertyHolderSupport.getPropertyNames() )
{
propertyHolderSupport.removeProperty( propertyName );
}
}
public boolean renameProperty( String name, String newName )
{
return PropertyExpansionUtils.renameProperty( propertyHolderSupport.getProperty( name ), newName, getTestCase() ) != null;
}
public void addTestPropertyListener( TestPropertyListener listener )
{
propertyHolderSupport.addTestPropertyListener( listener );
}
public Map<String, TestProperty> getProperties()
{
return propertyHolderSupport.getProperties();
}
public TestProperty getProperty( String name )
{
return propertyHolderSupport.getProperty( name );
}
public TestProperty getPropertyAt( int index )
{
return propertyHolderSupport.getPropertyAt( index );
}
public int getPropertyCount()
{
return propertyHolderSupport.getPropertyCount();
}
public List<TestProperty> getPropertyList()
{
return propertyHolderSupport.getPropertyList();
}
public String[] getPropertyNames()
{
return propertyHolderSupport.getPropertyNames();
}
public String getPropertyValue( String name )
{
return propertyHolderSupport.getPropertyValue( name );
}
public void removeTestPropertyListener( TestPropertyListener listener )
{
propertyHolderSupport.removeTestPropertyListener( listener );
}
public boolean hasProperty( String name )
{
return propertyHolderSupport.hasProperty( name );
}
public void setPropertyValue( String name, String value )
{
propertyHolderSupport.setPropertyValue( name, value );
}
public void setPropertyValue( String name, Object value )
{
setPropertyValue( name, String.valueOf( value ) );
}
public void moveProperty( String propertyName, int targetIndex )
{
propertyHolderSupport.moveProperty( propertyName, targetIndex );
}
public String getDriver()
{
return jdbcRequestTestStepConfig.getDriver();
}
public void setDriver( String d )
{
String old = getDriver();
jdbcRequestTestStepConfig.setDriver( d );
notifyPropertyChanged( "driver", old, d );
}
public String getConnectionString()
{
return jdbcRequestTestStepConfig.getConnectionString();
}
public void setConnectionString( String c )
{
String old = getConnectionString();
jdbcRequestTestStepConfig.setConnectionString( c );
notifyPropertyChanged( "connectionString", old, c );
}
public String getQuery()
{
return jdbcRequestTestStepConfig.getQuery();
}
public void setQuery( String q )
{
String old = getQuery();
jdbcRequestTestStepConfig.setQuery( q );
notifyPropertyChanged( "query", old, q );
}
public String getPassword()
{
return jdbcRequestTestStepConfig.getPassword();
}
public void setPassword( String p )
{
String old = getPassword();
jdbcRequestTestStepConfig.setPassword( p );
notifyPropertyChanged( "password", old, p );
}
public static boolean isNeededPassword( String connStr )
{
return !StringUtils.isNullOrEmpty( connStr ) ? connStr.contains( PASS_TEMPLATE ) : false;
}
public boolean isStoredProcedure()
{
return jdbcRequestTestStepConfig.getStoredProcedure();
}
public void setStoredProcedure( boolean sp )
{
String old = getPassword();
jdbcRequestTestStepConfig.setStoredProcedure( sp );
notifyPropertyChanged( "password", old, sp );
}
public JdbcRequest getJdbcRequest()
{
return jdbcRequest;
}
public String getQueryTimeout()
{
return jdbcRequestTestStepConfig.getQueryTimeout();
}
public String getMaxRows()
{
return jdbcRequestTestStepConfig.getMaxRows();
}
public String getFetchSize()
{
return jdbcRequestTestStepConfig.getFetchSize();
}
public void setQueryTimeout( String queryTimeout )
{
String old = getQueryTimeout();
jdbcRequestTestStepConfig.setQueryTimeout( queryTimeout );
notifyPropertyChanged( "queryTimeout", old, queryTimeout );
}
public void setMaxRows( String maxRows )
{
String old = getMaxRows();
jdbcRequestTestStepConfig.setMaxRows( maxRows );
notifyPropertyChanged( "maxRows", old, maxRows );
}
public void setFetchSize( String fetchSize )
{
String old = getFetchSize();
jdbcRequestTestStepConfig.setFetchSize( fetchSize );
notifyPropertyChanged( "fetchSize", old, fetchSize );
}
public void setResponse( JdbcResponse response, SubmitContext context )
{
JdbcResponse oldResponse = jdbcRequest.getResponse();
jdbcRequest.setResponse( response );
notifyPropertyChanged( RESPONSE_PROPERTY, oldResponse, response );
assertResponse( context );
}
public boolean isDiscardResponse()
{
return jdbcRequest.isDiscardResponse();
}
public void setDiscardResponse( boolean discardResponse )
{
jdbcRequest.setDiscardResponse( discardResponse );
}
public TestRequest getTestRequest()
{
return jdbcRequest;
}
public TestStep getTestStep()
{
return this;
}
@Override
public void prepare( TestCaseRunner testRunner, TestCaseRunContext testRunContext ) throws Exception
{
super.prepare( testRunner, testRunContext );
setResponse( null, testRunContext );
for( TestAssertion assertion : jdbcRequest.getAssertionList() )
{
assertion.prepare( testRunner, testRunContext );
}
}
}