Stuart winchester in Java 15 minutes

Creating Simple Soap Web Service Mocks With Camel

This article demonstrates how to get a SOAP web service up and running really quickly using Camel, Spring Boot and CXF. All based on the tremendous Fuse Integration Services 2.0 for Openshift.

Sometimes using SOAPUI for mocking Web Services is fine, however, quite often now we need everything to run IN the environment. Running services on your desktop doesn’t cut it anymore. So when we are performing integration testing it is always useful to have code running in the environment that will act more or less like the “real thing”.

Say for example we have a running SOAP webservice, and we harvest number of static responses we can use for this purpose, putting together a mock is pretty easy stuff thanks to the archetypes and the power of Camel.

Create our project

To start with ensure your maven repositories are configured, and then we should be able to run:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate \
  -DarchetypeCatalog=https://maven.repository.redhat.com/ga/io/fabric8/archetypes/archetypes-catalog/2.2.195-redhat-000016/archetypes-catalog-2.2.195.redhat-000016-archetype-catalog.xml \
  -DarchetypeGroupId=org.jboss.fuse.fis.archetypes \
  -DarchetypeArtifactId=spring-boot-camel-xml-archetype \
  -DarchetypeVersion=2.2.195.redhat-000016

This is creating a spring-boot camel project based on the spring-boot-camel-xml-archetype. This will be used as our base from which to build upon.

Next, we need to add further dependencies to the <dependencies> section of the pom.xml file. The following ensures that we have cxf and some groovy goodness.

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-cxf-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-cxf-transport</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-script</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-groovy</artifactId>
    </dependency>

Add our Static resources

Our WebService WSDL needs to be added to the project so that CXF can generate a service endpoint for it. We add this wsdl to src/main/resources/wsdl/simpleService.wsdl.

The following are static responses that will be returned to the client:

src/main/resources/response/response1.xml src/main/resources/response/response2.xml src/main/resources/response/response3.xml src/main/resources/response/response4.xml src/main/resources/response/response5.xml

Write the code

We will just modify the traditional camel context at src/main/resources/spring/camel-context.xml to have the following:

  1. A CXF Service Endpoint
  2. A Simple route which:
    • Exposes the CXF Service with MESSAGE dataFormat
    • Generates a random number between 1 and 5 using the Camel Simple Language
    • Sets the Body with groovy to read in the full file resource.

Not much code!

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="cxf:bean:simpleServiceEndpoint?dataFormat=MESSAGE"/>
        <setHeader headerName="randomResponse">
            <simple>random(1,6)</simple>
        </setHeader>
        <setBody>
            <groovy>this.getClass().getResource( "/response/response${request.headers.randomResponse}.xml" ).text</groovy>
        </setBody>
    </route>
</camelContext>
<cxf:cxfEndpoint id="simpleServiceEndpoint" address="/simpleService" wsdlURL="classpath:wsdl/simpleService.wsdl" />

Run the Code - Locally

mvn clean spring-boot:run will run the project locally. Open a browser and navigate to http://localhost:8080/services/ to see the cxf service endpoints:

CXF Services!

XML Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sim="http://www.example.org/SimpleService/">
   <soapenv:Header/>
   <soapenv:Body>
      <sim:NewOperation>
         <in>?</in>
      </sim:NewOperation>
   </soapenv:Body>
</soapenv:Envelope>
XML Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sim="http://www.example.org/SimpleService/">
   <soapenv:Header/>
   <soapenv:Body>
      <sim:NewOperationResponse>
         <out>hello5</out>
      </sim:NewOperationResponse>
   </soapenv:Body>
</soapenv:Envelope>
SOAPUI Screengrab:

SOAPUI!

Run the Code - In the Environment!

Login to minishift, or your openshift cluster and perform the following (my project is named camel-webservice-mocks):

oc new-project mocks
mvn clean fabric8:deploy
oc expose svc/camel-webservice-mock
MYROUTE=$(oc get routes -o json | jq -r .items[0].spec.host)
curl http://$MYROUTE/services

You should now see output from the standard cxf page. And if you navigate in your browser, you should see the endpoint served up via the Openshift cluster/minishift.

cxf-minishift!

Code / GitHub

All code for this post is available at https://github.com/welshstew/camel-webservice-mock.