=== General

`camel-quarkus-cxf-soap` uses extensions from the {link-quarkus-cxf-doc}[CXF Extensions for Quarkus] project - `quarkus-cxf`.
This means the set of supported use cases and WS specifications is largely given by `quarkus-cxf`.

IMPORTANT: To learn about supported use cases and WS specifications, see the Quarkus CXF {link-quarkus-cxf-doc}/reference/index.html[Reference].

=== Dependency management

The CXF and `quarkus-cxf` versions are xref:user-guide/dependency-management.adoc[managed] by {project-name}. You do not need select compatible versions for those projects.

=== Client

With `camel-quarkus-cxf-soap` (no additional dependencies required), you can use CXF clients as producers in Camel routes:

[source,java,subs="attributes+"]
----
import org.apache.camel.builder.RouteBuilder;
import {javaxOrJakartaPackagePrefix}.enterprise.context.ApplicationScoped;
import {javaxOrJakartaPackagePrefix}.enterprise.context.SessionScoped;
import {javaxOrJakartaPackagePrefix}.enterprise.inject.Produces;
import {javaxOrJakartaPackagePrefix}.inject.Named;

@ApplicationScoped
public class CxfSoapClientRoutes extends RouteBuilder {

    @Override
    public void configure() {

        /* You can either configure the client inline */
        from("direct:cxfUriParamsClient")
                .to("cxf://http://localhost:8082/calculator-ws?wsdlURL=wsdl/CalculatorService.wsdl&dataFormat=POJO&serviceClass=org.foo.CalculatorService");

        /* Or you can use a named bean produced below by beanClient() method */
        from("direct:cxfBeanClient")
                .to("cxf:bean:beanClient?dataFormat=POJO");

    }

    @Produces
    @SessionScoped
    @Named
    CxfEndpoint beanClient() {
        final CxfEndpoint result = new CxfEndpoint();
        result.setServiceClass(CalculatorService.class);
        result.setAddress("http://localhost:8082/calculator-ws");
        result.setWsdlURL("wsdl/CalculatorService.wsdl"); // a resource in the class path
        return result;
    }
}
----

The `CalculatorService` may look like the following:

[source,java,subs="attributes+"]
----
import {javaxOrJakartaPackagePrefix}.jws.WebMethod;
import {javaxOrJakartaPackagePrefix}.jws.WebService;

@WebService(targetNamespace = CalculatorService.TARGET_NS) // <1>
public interface CalculatorService {

    public static final String TARGET_NS = "http://acme.org/wscalculator/Calculator";

    @WebMethod // <1>
    public int add(int intA, int intB);

    @WebMethod // <1>
    public int subtract(int intA, int intB);

    @WebMethod // <1>
    public int divide(int intA, int intB);

    @WebMethod // <1>
    public int multiply(int intA, int intB);
}
----

<1> NOTE: JAX-WS annotations are required. The Simple CXF Frontend is not supported. Complex parameter types require JAXB annotations to work in properly in native mode.

[TIP]
====
You can test this client application against the https://quay.io/repository/l2x6/calculator-ws[quay.io/l2x6/calculator-ws:1.2] container that implements this service endpoint interface:

[source,shell]
----
$ docker run -p 8082:8080 quay.io/l2x6/calculator-ws:1.2
----
====

NOTE: `quarkus-cxf` supports {link-quarkus-cxf-doc}/user-guide/first-soap-client.html[injecting SOAP clients]
      using `@io.quarkiverse.cxf.annotation.CXFClient` annotation.
      Refer to the {link-quarkus-cxf-doc}/user-guide/first-soap-client.html[SOAP Clients] chapter of `quarkus-cxf` user guide for more details.

=== Server

With `camel-quarkus-cxf-soap`, you can expose SOAP endpoints as consumers in Camel routes.
No additional dependencies are required for this use case.

[source,java,subs="attributes+"]
----
import org.apache.camel.builder.RouteBuilder;
import {javaxOrJakartaPackagePrefix}.enterprise.context.ApplicationScoped;
import {javaxOrJakartaPackagePrefix}.enterprise.inject.Produces;
import {javaxOrJakartaPackagePrefix}.inject.Named;

@ApplicationScoped
public class CxfSoapRoutes extends RouteBuilder {

    @Override
    public void configure() {
        /* A CXF Service configured through a CDI bean */
        from("cxf:bean:helloBeanEndpoint")
                .setBody().simple("Hello $\{body} from CXF service");

        /* A CXF Service configured through Camel URI parameters */
        from("cxf:///hello-inline?wsdlURL=wsdl/HelloService.wsdl&serviceClass=org.foo.HelloService")
                        .setBody().simple("Hello $\{body} from CXF service");
    }

    @Produces
    @ApplicationScoped
    @Named
    CxfEndpoint helloBeanEndpoint() {
        final CxfEndpoint result = new CxfEndpoint();
        result.setServiceClass(HelloService.class);
        result.setAddress("/hello-bean");
        result.setWsdlURL("wsdl/HelloService.wsdl");
        return result;
    }
}
----

The path under which these two services will be served depends on the value of `quarkus.cxf.path`
{link-quarkus-cxf-doc}/reference/extensions/quarkus-cxf.html#quarkus-cxf_quarkus.cxf.path[configuration property]
which can for example be set in `application.properties`:

.application.properties
[source,properties]
----
quarkus.cxf.path = /soap-services
----

With this configuration in place, our two services can be reached under `http://localhost:8080/soap-services/hello-bean`
and `http://localhost:8080/soap-services/hello-inline` respectively.

The WSDL can be accessed by adding `?wsdl` to the above URLs.

[IMPORTANT]
====
Do not use `quarkus.cxf.path = /` in your application unless you are 100% sure that no other extension will want to expose HTTP endpoints.

Before `quarkus-cxf` 2.0.0 (i.e. before {project-name} 3.0.0), the default value of `quarkus.cxf.path` was `/`. The default was changed because it prevented other Quarkus extensions from exposing any further HTTP endpoints.
Among others, RESTEasy, Vert.x, SmallRye Health (no health endpoints exposed!) were impacted by this.
====

NOTE: `quarkus-cxf` supports alternative ways of exposing SOAP endpoints.
      Refer to the {link-quarkus-cxf-doc}/user-guide/first-soap-web-service.html[SOAP Services] chapter of `quarkus-cxf` user guide for more details.

=== Logging of requests and responses

You can enable verbose logging of SOAP messages for both clients and servers with `org.apache.cxf.ext.logging.LoggingFeature`:

[source,java,subs="attributes+"]
----
import org.apache.camel.builder.RouteBuilder;
import org.apache.cxf.ext.logging.LoggingFeature;
import {javaxOrJakartaPackagePrefix}.enterprise.context.ApplicationScoped;
import {javaxOrJakartaPackagePrefix}.enterprise.context.SessionScoped;
import {javaxOrJakartaPackagePrefix}.enterprise.inject.Produces;
import {javaxOrJakartaPackagePrefix}.inject.Named;

@ApplicationScoped
public class MyBeans {

    @Produces
    @ApplicationScoped
    @Named("prettyLoggingFeature")
    public LoggingFeature prettyLoggingFeature() {
        final LoggingFeature result = new LoggingFeature();
        result.setPrettyLogging(true);
        return result;
    }

    @Inject
    @Named("prettyLoggingFeature")
    LoggingFeature prettyLoggingFeature;

    @Produces
    @SessionScoped
    @Named
    CxfEndpoint cxfBeanClient() {
        final CxfEndpoint result = new CxfEndpoint();
        result.setServiceClass(CalculatorService.class);
        result.setAddress("https://acme.org/calculator");
        result.setWsdlURL("wsdl/CalculatorService.wsdl");
        result.getFeatures().add(prettyLoggingFeature);
        return result;
    }

    @Produces
    @ApplicationScoped
    @Named
    CxfEndpoint helloBeanEndpoint() {
        final CxfEndpoint result = new CxfEndpoint();
        result.setServiceClass(HelloService.class);
        result.setAddress("/hello-bean");
        result.setWsdlURL("wsdl/HelloService.wsdl");
        result.getFeatures().add(prettyLoggingFeature);
        return result;
    }
}
----

NOTE: The support for `org.apache.cxf.ext.logging.LoggingFeature` is provided by `io.quarkiverse.cxf:quarkus-cxf-rt-features-logging` as a `camel-quarkus-cxf-soap` dependency. You do not need to add it explicitly to your application.

=== WS Specifications

The extent of supported WS specifications is given by the Quarkus CXF project.

`camel-quarkus-cxf-soap` covers only the following specifications via the `{link-quarkus-cxf-doc}/reference/extensions/quarkus-cxf.html[io.quarkiverse.cxf:quarkus-cxf]` extension:

* JAX-WS
* JAXB
* WS-Addressing
* WS-Policy
* MTOM

If your application requires some other WS specification, such as WS-Security or WS-Trust, you must add an additional Quarkus CXF dependency covering it.
Refer to Quarkus CXF {link-quarkus-cxf-doc}/reference/index.html[Reference] page to see which WS specifications are covered by which Quarkus CXF extensions.

TIP: Both {project-name} and Quarkus CXF contain a number of
     {link-camel-quarkus-source}/integration-test-groups/cxf-soap[integration]
     {link-quarkus-cxf-source}/integration-tests[tests] which can serve as executable examples
     of applications that implement various WS specifications.

=== Tooling

`quarkus-cxf` wraps the following two CXF tools:

* `wsdl2Java` - for {link-quarkus-cxf-doc}/user-guide/first-soap-client.html#wsdl2java[generating service classes from WSDL]
* `java2ws` - for {link-quarkus-cxf-doc}/user-guide/generate-wsdl-from-java.html[generating WSDL from Java classes]

IMPORTANT: For `wsdl2Java` to work properly, your application will have to directly depend on `io.quarkiverse.cxf:quarkus-cxf`.

[TIP]
====
While `wsdlvalidator` is not supported, you can use `wsdl2Java` with the following configuration in `application.properties` to validate your WSDLs:

.application.properties
[source,properties]
----
quarkus.cxf.codegen.wsdl2java.additional-params = -validate
----
====
