Creating an asynchronous REST MockService in SoapUI with launch in Portainer

Task

Develop a mock for testing asynchronous messaging with an external system.





As an example, consider a case of checking the validity of a promotional code by an external system. Step by step:





1) We send a request to the service of an external system;





The PUT request contains fields (for example, in headers):





  • promotionalCode = correctPromotionalCode





  • correlationId = a random string to be returned to the callback





  • replyTo = address of the service receiving the callback





2) The external system responds synchronously - 204 No content;





3) After 5 seconds, the external system sends an asynchronous callback (to the replyTo address from the request):





POST request with message body:





  • status = "success" if the request promotionalCode is "correctPromotionalCode", otherwise "validationError" 





  • correlationId = correlationId from query





Decision

To solve this problem, we use SoapUI. This tool is quite flexible in terms of creating "smart" moxervices, as it allows you to write scripts both at the stages of starting / stopping moxervice (Start Script / Stop Script) and before / after receiving a request (OnRequest Script / AfterRequest Script).





Let's start:

1) Create a new project in SoapUI, for example, "test-soapui-project" (or select an existing one) and create two REST MockService for it.





Validation REST MockService - :





  • Path , , "/SP/ValidationSystem",





  • Port ,





  • Host "localhost".





 





Validation Receiving CALLBACK REST MockService - callback ( "Validation REST MockService" ):





  Path , , "/SP/SpHost"











2)  Validation REST MockService :





  • PUT









  • Resource Path , , "/validation" 





  • Method Rest , PUT ( 1 )





  • PUT  204 No content





:





  • Http Status Code ,  "204 - No Content",





  •   Content | Media type , "application/json".





  • Properties:





promotionalCode, replyTo, correlationId   PUT.





  • OnRequest Script - 204 No content ( 2 ). Properties:





*log.info  ,   script log.





  • AfterRequest Script - . callback , ( 5 ), callback replyTo ( 3 ):





:





log.info" Afterequest Script  - "
import java.lang.Exception
//    callback' ,    Properties
def replyTo = context.mockService.getPropertyValue('replyTo')
def correlationId = context.mockService.getPropertyValue('correlationId')
def promotionalCode = context.mockService.getPropertyValue('promotionalCode')
def status = "testStatus"
if ( promotionalCode.contains("correctPromotionalCode")){
status="success"
}
else
{
status="validationError"
}

// 
Thread.sleep(5000)

log.info"  callback"

//  callback -  POST
def conn = new URL(replyTo).openConnection();
def message = """\
{
"status":"${status}",
"correlationId":"${correlationId}"
}
"""
conn.setRequestMethod("POST")
conn.setDoOutput(true)
conn.setRequestProperty("Content-Type", "application/json")
conn.getOutputStream().write(message.getBytes("UTF-8"));
def postRC = conn.getResponseCode();
println(postRC);
if(postRC.equals(200)) {
println(conn.getInputStream().getText());
}

log.info"  callback"

log.info" Afterequest Script  - "
      
      



3)  Validation Receiving CALLBACK REST MockService  :





  • POST





:





  •   Resource Path , , "/callback"





  •   Method Rest , POST.





  • POST  200 OK





:





  •   Http Status Code ,  "200 - OK",





  • Content | Media type , "application/json".





  • OnRequest Script - , callback , :





4)





5)





, , Postman:





  • PUT validation 1 (Validation REST MockService), Headers 3 ,





  • replyTo callback - 2 (Validation Receiving CALLBACK REST MockService)





- 204 No Content.





script log SoapUI , callback 2:





Portainer:





1) images SoapUI:





  • docker hub .  fbascheper/soapui-mockservice-runner (https://hub.docker.com/r/fbascheper/soapui-mockservice-runner/)<o:p>





  • Portainer images









2)   :





  •  Compose file:





version: "3.7"
services: 
soapui-validation:
    image: fbascheper/soapui-mockservice-runner:latest
    volumes:
      - /soapui/soapui-prj:/home/soapui/soapui-prj
    environment:
      - MOCK_SERVICE_NAME=Validation REST MockService
      - PROJECT=/home/soapui/soapui-prj/test-soapui-project.xml
    ports:
      - 7703:8080
      
      



:





image - docker hub (https://hub.docker.com/r/fbascheper/soapui-mockservice-runner/)





volumes - soapUI , : " ": " "





MOCK_SERVICE_NAME - soapUI





PROJECT - soapUI , : ยซ " " volumesยป + ( test-soapui-project)





ports -  ( port soapUI), " ": " "





* in our example, the soapUI project was placed on the server in / soapui / soapui-prj /





  • go to Portainer in the Stacks section,





  • add a new stack:





    - specify in the Name field how our stack will be named, for example, sp-soapui-mocks,





    - copy the Compose file text in the Web editor,





  • Deploy the stack.





As a result, the sp-soapui-mocks stack will be formed, in which the service specified in the compose file is launched:





Total

We got an asynchronous moxervice that satisfies the task at hand. The service is launched on a common server and is available to all project participants. At the moment, he helps us develop and test the application in the absence of a third-party system API.








All Articles