=== 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]
----
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]
----
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]
----
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]
----
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 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, 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
----
