Thursday, 8 December 2011

Load Response Message File System in SoapUI

Today I figured out how to get a response from filesystem in SoapUI. I found that I could not dynamically select from multiple responses in a mockResponse-TestStep in a TestSuite. But loading from a file within a Groovy script should do the job. Advantage is also that you can have as many response files as you like. You just put a value in the filename, that you select using xpath from the request message. The folder in which you store the message can be put in a property on the mockService. I don't have the time to explain the whole lot. But the response in the mockService should be like:
<soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:header>
      <darwinheader xmlns="http://www.darwin-it.nl/XMLHeader/10">
         <headerversion>${headerVersion}</headerversion>
         <messageid>${messageId}</messageid>
         <servicerequestordomain>${serviceRequestorDomain}</servicerequestordomain>
         <servicerequestorid>${serviceRequestorId}</servicerequestorid>
         <serviceproviderdomain>${serviceProviderDomain}</serviceproviderdomain>
         <serviceid>${serviceId}</serviceid>
         <serviceversion≶${serviceVersion}</serviceversion>
         <faultindication>${faultIndication}</faultindication>
         <messagetimestamp>${messageTimestamp}</messagetimestamp>
      </darwinheader>
   </soapenv:header>
   <soapenv:body>${responseBody}</soapenv:body>
</soapenv:envelope>
Here you see that the Soapenvelope with the header is given, but the diffent values are properties, as well as the responseBody. The script to get these from the request is as follows:
def method = "ChangeServiceRequest.Response 1.Script"
log.info("Start "+method)

log.info(mockRequest.requestContent)

def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
// Set Namespaces
def holder = groovyUtils.getXmlHolder(mockRequest.requestContent)
holder.namespaces["soapenv"] = "http://schemas.xmlsoap.org/soap/envelope/"
holder.namespaces["ns"] = "http://www.darwin-it.nl/XMLHeader/10"
holder.namespaces["rpy"] = "http://www.darwin-it.nl/ChangeServiceRequest/2/Rpy"


log.info("Get Header Properties")
context.messageId=Math.random()
log.info("messageId: "+context.messageId)
context.headerVersion= holder.getNodeValue("//ns:DarwinHeader/ns:HeaderVersion")
log.info("headerVersion: "+context.headerVersion)
context.serviceRequestorDomain= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceRequestorDomain")
log.info("ServiceRequestorDomain: "+context.serviceRequestorDomain)
context.serviceRequestorId= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceRequestorId")
log.info("serviceRequestorId: "+context.serviceRequestorId)
context.serviceProviderDomain= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceProviderDomain")
log.info("serviceProviderDomain: "+context.serviceProviderDomain)
context.serviceId= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceId")
log.info("serviceId: "+context.serviceId)
context.serviceVersion= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceVersion")
log.info("serviceVersion: "+context.serviceVersion)
context.faultIndication= holder.getNodeValue("//ns:DarwinHeader/ns:FaultIndication")
log.info("faultIndication: "+context.faultIndication)
context.messageTimestamp= holder.getNodeValue("//ns:DarwinHeader/ns:MessageTimestamp")
log.info("messageTimestamp: "+context.messageTimestamp)

def serviceRequestNr= holder.getNodeValue("//req:ChangeServiceRequest_Req/req:ServiceRequestData/req:ServiceRequestNumber")
log.info("ServiceRequestNr: "+serviceRequestNr)

def mockRunner = context.getMockRunner()
def mockService = mockRunner.mockService
def filePath = mockService.getPropertyValue( "responseFilePath")+"/FT01_ChangeServiceRequest_"+serviceRequestNr+".xml"
log.info("FileName: "+ filePath)
def File file = new File( filePath )
def fileLength = (int) file.length();
def buffer = new char[fileLength];
def inputReader = new FileReader(file);
def numChar = inputReader.read(buffer);
requestContext.responseBody = new String(buffer);
log.info("End "+method)
With "def holder = groovyUtils.getXmlHolder(mockRequest.requestContent)" you get an XML object of the request. The lines "holder.namespaces["ns"] = "http://www.darwin-it.nl/XMLHeader/10" set the namespace-abbreviations, needed to select the values from the request.
Then with "def serviceRequestNr= holder.getNodeValue("//req:ChangeServiceRequest_Req/req:ServiceRequestData/req:ServiceRequestNumber")", you can perform an xpath query, to get the serviceRequestNr from the request message in this case.

The lines
def mockRunner = context.getMockRunner()
def mockService = mockRunner.mockService
def filePath = mockService.getPropertyValue( "responseFilePath")

show how to read a property from the mockService.

Then the last lines are to determine the actual file path using this property and the  queried serviceRequestNr, and  to read the file.

By putting the file in the requestContext using: "requestContext.responseBody = new String(buffer);" it can be put in the response using the property "${responseBody}" like in the response-skeleton above. You might notice that it is a mixture of Java and Groovy. I'm not so familiar with Groovy yet. But I found that if it works in Java it is easy to get it work in Groovy. Actually, Groovy is just more loosely typed. I hope this clears enough to get this going. Good luck.

No comments: