Forum Discussion

ITAbteilung's avatar
ITAbteilung
Contributor
12 years ago

[Resolved] Mockup Request and Response Validation

Dear Smartbear-Team,

we are working with SoapUI Mockups and we want them to be strictly not allowing invalid requests and responses. So we are looking for a way to validate a the request when it comes in and the response before it goes out.
Is there already a functioniality provided by SoapUI to do so?

Thanks in advance,
Gilbert

12 Replies

  • SmartBear_Suppo's avatar
    SmartBear_Suppo
    SmartBear Alumni (Retired)
    Hi Gilbert,

    just a quick check; have you tried adding

    mockRequest.mockOperation = operation;

    before the "return mr" statement!?

    regards,

    /Ole
    SmartBear Software
  • Hi Ole,

    yes, now it works!! Thank you! Here is the whole generic solution for making a mockup validate the requests. The only requirement is that the project uses cached definitions.
    Note: There is some useless overhead in my solution ("parentclasses"), but acutally that is the structure we use and I'm too lazy to edit it just for posting it. The solution works fine.

    Call: Copy the following line in the OnRequest-Script:

    def validator = new validation.Validator( log, context, mockRequest, mockRunner);
    return validator.validateRequest();


    In SoapUI, go to File->Preferences->SoapUI Pro. Define a path to your Script Library, i.e. the directory where you want to store your .groovy files. Inside that directory, create a subdirectory called "validation" and one called "parentclasses".

    In the "parentclasses" directory: create a file called "OnRequest.groovy" and paste the following content:

    parentclasses/OnRequest.groovy

    package parentclasses

    import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunContext;
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner;
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockRequest;
    import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
    import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlValidator;


    class OnRequest extends ScriptHavingRequest{

    protected WsdlMockRunner mockRunner;

    public OnRequest( log, context, mockRequest, mockRunner){
    super( log, context, null, mockRequest);
    this.mockRunner = mockRunner;
    }
    }


    In the "parentclasses" directory: create a file called "ScriptHavingRequest.groovy" and paste the following content:
    parentclasses/ScriptHavingRequest.groovy

    package parentclasses

    import java.util.UUID;

    import com.eviware.soapui.impl.wsdl.WsdlTestCasePro;
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockRequest
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunContext
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation
    import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
    import com.eviware.soapui.support.XmlHolder
    import com.eviware.soapui.support.types.StringToObjectMap

    class ScriptHavingRequest {
    protected Logger log;
    protected WsdlMockRunContext context, requestContext;
    protected WsdlMockRequest mockRequest;
    protected XmlHolder requestHolder;

    public ScriptHavingRequest( log_, context_, requestContext_, mockRequest_){
    log = log_;
    context = context_;
    requestContext = requestContext_;
    mockRequest = mockRequest_;
    requestHolder = new XmlHolder( mockRequest.requestContent);
    }

    protected initNs( nameSpaceMap){
    if( nameSpaceMap != null){
    for( ns in nameSpaceMap.entrySet()){
    requestHolder.declareNamespace( ns?.key, ns?.value);
    }
    }
    }
    }


    In the "validation" directory: create a file called "Validator.groovy" and paste the following content:
    validation/Validator.groovy

    package validation

    import com.eviware.soapui.impl.wsdl.WsdlOperation;
    import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlValidator;
    import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation
    import com.eviware.soapui.impl.wsdl.panels.mockoperation.WsdlMockRequestMessageExchange;
    import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
    import com.eviware.soapui.model.iface.MessagePart
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;

    class Validator extends parentclasses.OnRequest{

    private final nameSpaceMap = ["soapenv":"http://schemas.xmlsoap.org/soap/envelope/"];

    public Validator( log, context, mockRequest, mockRunner){
    super( log, context, mockRequest, mockRunner);
    initNs( nameSpaceMap);
    }

    public validateRequest(){
    if( context.getMockService().getPropertyValue("requestValidation")?.equals("true")){
    def operationElementName = getOperationElementName();
    def operationName = operationElementToOperationName(operationElementName);
    if( operationName == null){
    String faultstring = "VALIDATION ERROR: The operation-element '" + operationElementName +
    "' can not be found. Are request and mockup of the same version?";
    log.info( faultstring);
    return createFaultResponse( faultstring, context.mockService.getMockedOperations().get(0));
    }
    WsdlContext wsdlcontext = context.mockService.getMockedInterfaces()[0].getDefinitionContext();
    WsdlValidator validator = new WsdlValidator(wsdlcontext);
    WsdlMockOperation operation = context.mockService.getMockOperationByName( operationName);
    WsdlMockRequestMessageExchange msgExchange = new WsdlMockRequestMessageExchange(mockRequest, operation);
    def errors = validator.assertRequest(msgExchange, /*envelopeOnly*/false);
    if (errors.length > 0 ){
    String validationErrors = "VALIDATION ERRORS: " + errors.collect(){ '\n' + it };
    log.info( validationErrors);
    return createFaultResponse( validationErrors, operation);
    }
    log.info("Request Validation OK!");
    }else{
    log.info("No Request Validation has been performed.")
    }
    }

    private String getOperationElementName(){
    Element bodyElement = requestHolder.getDomNode( "//soapenv:Body");
    def operationElement = bodyElement.getChildNodes().item(0);
    while (operationElement && operationElement.nodeType != 1) {//nodeType 1 is Element
    operationElement = operationElement.nextSibling;
    }
    def operationElementName = operationElement.getNodeName();
    if( operationElementName.contains(':')){
    operationElementName = operationElementName.split(':')[1];
    }
    return operationElementName;
    }

    private String operationElementToOperationName(String operationElementName) {
    for( WsdlOperation wo : context.mockService.getMockedOperations()){
    //log.info( "- Operation: " + wo.getName())
    for( MessagePart mp : wo.getDefaultRequestParts()){
    String partElementName = mp.getProperties().get("partElementName");
    if( partElementName.contains('}')){
    int idx = partElementName.indexOf('}');
    partElementName = partElementName.substring(idx+1, partElementName.length());
    }
    //log.info( " " + partElementName);
    if( operationElementName.equals(partElementName)){
    return wo.getName();
    }
    }
    }
    return null;
    }

    private WsdlMockResult createFaultResponse( String faultstring){
    String content = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
    <soapenv:Fault>
    <faultcode>Server</faultcode>
    <faultstring><![CDATA[''' + faultstring + ''']]></faultstring>
    </soapenv:Fault>
    </soapenv:Body>
    </soapenv:Envelope>''';
    WsdlMockResult mr = new WsdlMockResult(mockRequest);
    mockRequest.httpResponse.writer << content;
    mockRequest.httpResponse.status = 500;
    log.info( "Validation Errors: " + faultstring);
    return mr;
    }

    private WsdlMockResult createFaultResponse( String faultstring, operation){
    String content = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
    <soapenv:Fault>
    <faultcode>Server</faultcode>
    <faultstring><![CDATA[''' + faultstring + ''']]></faultstring>
    </soapenv:Fault>
    </soapenv:Body>
    </soapenv:Envelope>''';
    WsdlMockResult mr = new WsdlMockResult(mockRequest);
    mockRequest.httpResponse.writer << content;
    mockRequest.httpResponse.status = 500;
    mockRequest.mockOperation = operation;
    return mr;
    }
    }


    Have Fun!

    Best regards,
    Gilbert