Your first SOAP Client on Quarkus
In this guide we explain how to create a simple Quarkus application acting as a client of a remote Web service.
|
Create project first
Follow the Project creation guide before proceeding here. |
Remote Web service for testing
First, we need some remote Web service to connect to. We can use a simple Calculator Web service running in a container for that purpose.
$ docker run -p 8082:8080 quay.io/l2x6/calculator-ws:1.0
Once the container is up and running, we can inspect its WSDL
$ curl -s http://localhost:8082/calculator-ws/CalculatorService?wsdl
<?xml version="1.0" ?>
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.jboss.org/eap/quickstarts/wscalculator/Calculator" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="CalculatorService" targetNamespace="http://www.jboss.org/eap/quickstarts/wscalculator/Calculator">
...
<wsdl:binding name="CalculatorServiceSoapBinding" type="tns:CalculatorService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>
<wsdl:operation name="add">
<soap:operation soapAction="" style="document"></soap:operation>
<wsdl:input name="add">
<soap:body use="literal"></soap:body>
</wsdl:input>
<wsdl:output name="addResponse">
<soap:body use="literal"></soap:body>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="subtract">
<soap:operation soapAction="" style="document"></soap:operation>
<wsdl:input name="subtract">
<soap:body use="literal"></soap:body>
</wsdl:input>
<wsdl:output name="subtractResponse">
<soap:body use="literal"></soap:body>
</wsdl:output>
</wsdl:operation>
...
</wsdl:binding>
...
</wsdl:definitions>
As you can see in the WSDL, the service offers some basic arithmetic operations, such as add, subtract, etc.
Let’s test it with curl:
$ curl -s \
-X POST \
-H "Content-Type: text/xml;charset=UTF-8" \
-d \
'<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<add xmlns="http://www.jboss.org/eap/quickstarts/wscalculator/Calculator">
<arg0 xmlns="">7</arg0> (1)
<arg1 xmlns="">4</arg1>
</add>
</Body>
</Envelope>' \
http://localhost:8082/calculator-ws/CalculatorService
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:addResponse xmlns:ns2="http://www.jboss.org/eap/quickstarts/wscalculator/Calculator">
<return>11</return> (2)
</ns2:addResponse>
</soap:Body>
</soap:Envelope>
| 1 | The request to add 7 and 4 |
| 2 | 11 - return value of the operation |
SOAP client
Now let’s have a look how we can get the client inside a Quarkus application.
First, we need the Service Endpoint Interface (SEI) and all other model classes it requires.
There are several ways to get them:
-
Write by hand
-
Copy from the Web Sevice project, if it is written in Java
-
Have a Maven artifact containing the model classes, perhaps it is offered by the Service project
-
Generate the model classes from WSDL
The last option tends to be the easiest and most flexible for client applications.
|
If you want to use this approach, first follow the Generate Java from WSDL section and then continue with the next steps. |
Using SEI as a client
In our case, the Service Endpoint Interface (SEI) is org.jboss.eap.quickstarts.wscalculator.calculator.CalculatorService.
As usual on Quarkus, we can obtain an instance of it via CDI.
To make it testable easily, we’ll wrap it in a REST service:
package io.quarkiverse.cxf.client.it;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import org.jboss.eap.quickstarts.wscalculator.calculator.CalculatorService;
import io.quarkiverse.cxf.annotation.CXFClient;
@Path("/cxf/calculator-client")
public class CxfClientRestResource {
@CXFClient("myCalculator") (1)
CalculatorService myCalculator;
@GET
@Path("/add")
@Produces(MediaType.TEXT_PLAIN)
public int add(@QueryParam("a") int a, @QueryParam("b") int b) {
return myCalculator.add(a, b); (2)
}
}
| 1 | Let the CDI container inject an instance of the client. @CXFClient("myCalculator") is actually equivalent to @Inject @CXFClient("myCalculator") |
| 2 | Invoke the add operation thus calling the remote Web service |
Is this all we need for the client to work?
- No, in addition to the above, we need to tell a few other things to the CXF Quarkus extension in application.properties:
cxf.it.calculator.baseUri=http://localhost:8082
quarkus.cxf.client.myCalculator.wsdl = ${cxf.it.calculator.baseUri}/calculator-ws/CalculatorService?wsdl
quarkus.cxf.client.myCalculator.client-endpoint-url = ${cxf.it.calculator.baseUri}/calculator-ws/CalculatorService
quarkus.cxf.client.myCalculator.service-interface = org.jboss.eap.quickstarts.wscalculator.calculator.CalculatorService
|
All client configuration properties are documented in the Configuration properties reference. |
With all the above files in place, we should be able to start the application in Quarkus dev mode
$ mvn quarkus:dev
...
INFO [io.quarkus] (Quarkus Main Thread) ... Listening on: http://localhost:8080
and test it by sending some requests to it:
$ curl -s 'http://localhost:8080/cxf/calculator-client/add?a=5&b=6'
11
where 11 is the correct result of adding 5 and 6.