Skip to content

Latest commit

 

History

History
 
 

cxf-soap

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Camel Quarkus CXF SOAP example

{cq-description}

In this example we will create two SOAP webservices with two different approaches. Both services will use Camel routes as service implementation exposed via CXF component.

WSDL first

The "WSDL first" approach presupposes writing the WSDL file manually at the beginning of the SOAP service design. Then we can use the generate-code goal of quarkus-maven-plugin to generate the Java classes for us. The wsdl2java tool is used under the hood and its configuration can be found in application.properties.

The customer web service is exposed via Camel route endpoint cxf:bean:customer. Its logic is implemented directly in the route by delegating to org.acme.cxf.soap.wsdl.repository.CustomerRepository. The endpoint supports two SOAP operations: getCustomersByName and updateCustomer.

Note
Most modern IDEs will be able to discover the generared classes automatically. You may want to check some occurrences of those in org.acme.cxf.soap.wsdl.repository.CustomerRepository.
Tip
More information about generating Java classes from WSDL can be found in Java from WSDL chapter of Quarkus CXF documentation.

Binding (Advanced)

For illustrating how other wsdl2java options could be applied via quarkus.cxf.codegen.wsdl2java.additional-params, we have added a custom binding defined in binding.xml. It instructs CXF to use LocalDate (more common in Java world) instead of default XML Date representation XMLGregorianCalendar.

Java first

If you don’t have the WSDL file upfront, you can create your SOAP service from Java classes annotated with JAX-WS annotations. Check the org.acme.cxf.soap.pojo.service.ContactService interface as an example. Again, we implement the service interface in a Camel fashion, this time through a bean - see org.acme.cxf.soap.pojo.service.impl.ContactServiceInMemoryImpl.

The exposed contact web service will enable five operations - addContact, getContact, getContacts, updateContact and removeContact.

Tip
If you would like to only generate WSDL from Java, you can follow the WSDL from Java chapter of Quarkus CXF documentation.

Start in the Development mode

$ mvn clean compile quarkus:dev

The above command compiles the project, starts the application and lets the Quarkus tooling watch for changes in your workspace. Any modifications in your project will automatically take effect in the running application.

Tip
Please refer to the Development mode section of Camel Quarkus User guide for more details.

Playground

We can first try to add a contact with:

curl -X POST -H "Content-Type: text/xml;charset=UTF-8" -d @src/main/resources/requests/contact/add.xml http://localhost:8080/cxf/services/contact

Then verify it was added with:

$ curl -X POST -H "Content-Type: text/xml;charset=UTF-8" -d @src/main/resources/requests/contact/getAll.xml http://localhost:8080/cxf/services/contact

Which should return:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:getContactsResponse xmlns:ns2="http://camel.apache.org/test/ContactService">
      <return>
        <contacts>
          <name>Lukas</name>
          <address>
            <city>New York</city>
            <street>Sky 1234</street>
          </address>
          <type>PERSONAL</type>
        </contacts>
      </return>
    </ns2:getContactsResponse>
  </soap:Body>
</soap:Envelope>

We can also test our customer service:

$ curl -X POST -H "Content-Type: text/xml;charset=UTF-8" -d @src/main/resources/requests/customer/getByName.xml http://localhost:8080/cxf/services/customer

You can observe that we have hardcoded test as the name in the SOAPBody part in src/main/resources/requests/customer/getByName.xml as follows:

<cus:getCustomersByName>
  <name>test</name>
</cus:getCustomersByName>

We can try to alter it to non-valid request (the validation is enabled with schema-validation-enabled=true in org.acme.cxf.soap.wsdl.MyWsdlRouteBuilder). For example, you can change test to t. Once you invoke the service again, you should see the following exception:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode>soap:Client</faultcode>
      <faultstring>Unmarshalling Error: cvc-minLength-valid: Value 't' with length = '1' is not facet-valid with respect to minLength '2' for type '#AnonType_namegetCustomersByName'.</faultstring>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

The last thing which could be tested, is trying to get a non-existent customer (which t was obviously as well, but now we will pass it through schema validation). So change the name to Non existent and see result with NoSuchCustomer:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode>soap:Server</faultcode>
      <faultstring>Customer not found</faultstring>
      <detail>
        <ns2:NoSuchCustomer xmlns:ns2="http://customerservice.example.com/">
          <customerName>Non existent</customerName>
        </ns2:NoSuchCustomer>
      </detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>
Tip
To obtain WSDLs for any exposed CXF service, you can query URL http://<hostname>/<cxf-path>?wsdl. It can be handy in tools like SoapUI.

To discover WSDLs of our services, you can use:

$ curl "http://localhost:8080/cxf/services/contact?wsdl"
$ curl "http://localhost:8080/cxf/services/customer?wsdl"

Package and run the application

Once you are done with playing/developing you may want to package and run the application for production usage.

Tip
Find more details about the JVM mode and Native mode in the Package and run section of Camel Quarkus User guide

JVM mode

$ mvn clean package
$ java -jar target/quarkus-app/quarkus-run.jar

Native mode

Important
Native mode requires having GraalVM and other tools installed. Please check the Prerequisites section of Camel Quarkus User guide.

To prepare a native executable using GraalVM, run the following command:

$ mvn clean package -Pnative
$ ./target/*-runner

Kubernetes

Deploy

$ mvn clean package -DskipTests -Dquarkus.kubernetes.deploy=true -Dkubernetes

You should see one pod running:

camel-quarkus-examples-cxf-soap-cd9477f94-qb8vv   1/1     Running   0          43s

Then use following command to redirect the localhost network to the Kubernetes network:

$ kubectl port-forward service/camel-quarkus-examples-cxf-soap 8080:8080

Open another terminal and then follow instructions from Playground.

To stop it you can CTRL+C the process in the port-forwarding terminal and shutdown the Kubernetes cluster.

Feedback

Please report bugs and propose improvements via GitHub issues of Camel Quarkus project.