You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by fm...@apache.org on 2026/08/28 10:12:24 UTC
(camel) branch main updated: CAMEL-24477: camel-cxf - add a muteException consumer option (#25742)
This is an automated email from the ASF dual-hosted git repository.
Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new fd4fd273e4d1 CAMEL-24477: camel-cxf - add a muteException consumer option (#25742)
fd4fd273e4d1 is described below
commit fd4fd273e4d1d36c1341cc8cf08405decd8c755c
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Fri Aug 28 12:12:18 2026 +0200
CAMEL-24477: camel-cxf - add a muteException consumer option (#25742)
CxfConsumer built the SOAP fault from whatever reached Exchange.getException(),
so the exception's message - or its class name when it had none - became the
faultstring returned to the caller. The http consumers gained a muteException
option defaulting to true in CAMEL-23651; camel-cxf had none.
Muting is narrower here than in the other consumers because for a SOAP service
some faults are the contract. Only an undeclared failure is replaced: a CXF
Fault, an exception annotated @WebFault, and a Throwable or <soap:Fault>
CxfPayload set as the message body are all still returned in full. checkFailure
now separates the exception path from the body path to make that distinction,
which retires extractThrowable.
The stand-in has its stack trace cleared, since CXF can be configured to put
the stack trace in the fault detail.
Note this also covers framework failures: a continuationTimeout expiry no
longer reports its timeout to the caller, so
CxfConsumerContinuationTimeoutTest sets muteException=false.
Co-authored-by: Federico Mariani <34...@users.noreply.github.com>
---
.../org/apache/camel/catalog/components/cxf.json | 69 ++++++-------
components/camel-cxf/camel-cxf-soap/pom.xml | 6 ++
.../component/cxf/jaxws/CxfEndpointConfigurer.java | 6 ++
.../component/cxf/jaxws/CxfEndpointUriFactory.java | 3 +-
.../org/apache/camel/component/cxf/jaxws/cxf.json | 69 ++++++-------
.../camel/component/cxf/jaxws/CxfConsumer.java | 40 ++++++--
.../camel/component/cxf/jaxws/CxfEndpoint.java | 16 +++
.../jaxws/CxfConsumerContinuationTimeoutTest.java | 71 ++++++-------
.../cxf/jaxws/CxfConsumerMuteExceptionTest.java | 111 +++++++++++++++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_23.adoc | 32 ++++++
.../endpoint/dsl/CxfEndpointBuilderFactory.java | 42 ++++++++
11 files changed, 352 insertions(+), 113 deletions(-)
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cxf.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cxf.json
index 92494c9f92ac..bf5a8ac7f9ce 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cxf.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cxf.json
@@ -46,39 +46,40 @@
"address": { "index": 1, "kind": "path", "displayName": "Address", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The service publish address." },
"dataFormat": { "index": 2, "kind": "parameter", "displayName": "Data Format", "group": "common", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.cxf.common.DataFormat", "enum": [ "PAYLOAD", "RAW", "MESSAGE", "CXF_MESSAGE", "POJO" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "POJO", "description": "The data type messages supported by the CXF endpoint." },
"wrappedStyle": { "index": 3, "kind": "parameter", "displayName": "Wrapped Style", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "The WSDL style that describes how parameters are represented in the SOAP body. If the value is false, CXF will chose the document-literal unwrapped style, If the value is true, CXF will chose the document- [...]
- "bridgeErrorHandler": { "index": 4, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
- "exceptionHandler": { "index": 5, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By def [...]
- "exchangePattern": { "index": 6, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "enum", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
- "cookieHandler": { "index": 7, "kind": "parameter", "displayName": "Cookie Handler", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.http.base.cookie.CookieHandler", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a cookie handler to maintain a HTTP session" },
- "defaultOperationName": { "index": 8, "kind": "parameter", "displayName": "Default Operation Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationName that will be used by the CxfProducer which invokes the remote service." },
- "defaultOperationNamespace": { "index": 9, "kind": "parameter", "displayName": "Default Operation Namespace", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationNamespace that will be used by the CxfProducer which invokes the remote service." },
- "hostnameVerifier": { "index": 10, "kind": "parameter", "displayName": "Hostname Verifier", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier", "deprecated": false, "autowired": false, "secret": false, "description": "The hostname verifier to be used. Use the # notation to reference a HostnameVerifier from the registry." },
- "sslContextParameters": { "index": 11, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "The Camel SSL setting reference. Use the # notation to reference the SSL Context." },
- "wrapped": { "index": 12, "kind": "parameter", "displayName": "Wrapped", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Which kind of operation that CXF endpoint producer will invoke" },
- "lazyStartProducer": { "index": 13, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
- "synchronous": { "index": 14, "kind": "parameter", "displayName": "Synchronous", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used" },
- "allowStreaming": { "index": 15, "kind": "parameter", "displayName": "Allow Streaming", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the CXF component, when running in PAYLOAD mode, will DOM parse the incoming messages into DOM Elements or keep the payload as a javax.xml.transform.Source objec [...]
- "bus": { "index": 16, "kind": "parameter", "displayName": "Bus", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.cxf.Bus", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom configured CXF Bus." },
- "continuationTimeout": { "index": 17, "kind": "parameter", "displayName": "Continuation Timeout", "group": "advanced", "label": "advanced", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "30000", "description": "This option is used to set the CXF continuation timeout which could be used in CxfConsumer by default when the CXF server is using Jetty or Servlet transport." },
- "cxfBinding": { "index": 18, "kind": "parameter", "displayName": "Cxf Binding", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.common.CxfBinding", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom CxfBinding to control the binding between Camel Message and CXF Message." },
- "cxfConfigurer": { "index": 19, "kind": "parameter", "displayName": "Cxf Configurer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.jaxws.CxfConfigurer", "deprecated": false, "autowired": false, "secret": false, "description": "This option could apply the implementation of org.apache.camel.component.cxf.CxfEndpointConfigurer which supports to configure the CXF endpoint in programmatic way. User can configure [...]
- "defaultBus": { "index": 20, "kind": "parameter", "displayName": "Default Bus", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will set the default bus when CXF endpoint create a bus by itself" },
- "headerFilterStrategy": { "index": 21, "kind": "parameter", "displayName": "Header Filter Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HeaderFilterStrategy to filter header to and from Camel message." },
- "mergeProtocolHeaders": { "index": 22, "kind": "parameter", "displayName": "Merge Protocol Headers", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to merge protocol headers. If enabled then propagating headers between Camel and CXF becomes more consistent and similar. For more details see CAMEL-6393." },
- "mtomEnabled": { "index": 23, "kind": "parameter", "displayName": "Mtom Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To enable MTOM (attachments). This requires to use POJO or PAYLOAD data format mode." },
- "properties": { "index": 24, "kind": "parameter", "displayName": "Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "properties.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "To set additional CXF options using the key\/value pairs from the Map. For example to turn on stacktraces in SOAP faults, properties.faultStackTra [...]
- "schemaValidationEnabled": { "index": 25, "kind": "parameter", "displayName": "Schema Validation Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable schema validation for request and response. Disabled by default for performance reason" },
- "skipPayloadMessagePartCheck": { "index": 26, "kind": "parameter", "displayName": "Skip Payload Message Part Check", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether SOAP message validation should be disabled." },
- "loggingFeatureEnabled": { "index": 27, "kind": "parameter", "displayName": "Logging Feature Enabled", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option enables CXF Logging Feature which writes inbound and outbound SOAP messages to log." },
- "loggingSizeLimit": { "index": 28, "kind": "parameter", "displayName": "Logging Size Limit", "group": "logging", "label": "logging", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 49152, "description": "To limit the total size of number of bytes the logger will output when logging feature has been enabled and -1 for no limit." },
- "skipFaultLogging": { "index": 29, "kind": "parameter", "displayName": "Skip Fault Logging", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the PhaseInterceptorChain skips logging the Fault that it catches." },
- "password": { "index": 30, "kind": "parameter", "displayName": "Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of password for the CXF client." },
- "username": { "index": 31, "kind": "parameter", "displayName": "Username", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of username for the CXF client." },
- "bindingId": { "index": 32, "kind": "parameter", "displayName": "Binding Id", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The bindingId for the service model to use." },
- "portName": { "index": 33, "kind": "parameter", "displayName": "Port Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint name this service is implementing, it maps to the wsdl:portname. In the format of ns:PORT_NAME where ns is a namespace prefix valid at this scope." },
- "publishedEndpointUrl": { "index": 34, "kind": "parameter", "displayName": "Published Endpoint Url", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can override the endpointUrl that published from the WSDL which can be accessed with service address url plus wsd" },
- "serviceClass": { "index": 35, "kind": "parameter", "displayName": "Service Class", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "The class name of the SEI (Service Endpoint Interface) class which could have JSR181 annotation or not." },
- "serviceName": { "index": 36, "kind": "parameter", "displayName": "Service Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The service name this service is implementing, it maps to the wsdl:servicename." },
- "wsdlURL": { "index": 37, "kind": "parameter", "displayName": "Wsdl URL", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The location of the WSDL. Can be on the classpath, file system, or be hosted remotely." }
+ "muteException": { "index": 4, "kind": "parameter", "displayName": "Mute Exception", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "If enabled and an Exchange failed processing on the consumer side, and the exception is not a SOAP fault the service contract declares, the SOAP fault returned to the caller won't contain the exception's [...]
+ "bridgeErrorHandler": { "index": 5, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
+ "exceptionHandler": { "index": 6, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By def [...]
+ "exchangePattern": { "index": 7, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "enum", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+ "cookieHandler": { "index": 8, "kind": "parameter", "displayName": "Cookie Handler", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.http.base.cookie.CookieHandler", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a cookie handler to maintain a HTTP session" },
+ "defaultOperationName": { "index": 9, "kind": "parameter", "displayName": "Default Operation Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationName that will be used by the CxfProducer which invokes the remote service." },
+ "defaultOperationNamespace": { "index": 10, "kind": "parameter", "displayName": "Default Operation Namespace", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationNamespace that will be used by the CxfProducer which invokes the remote service." },
+ "hostnameVerifier": { "index": 11, "kind": "parameter", "displayName": "Hostname Verifier", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier", "deprecated": false, "autowired": false, "secret": false, "description": "The hostname verifier to be used. Use the # notation to reference a HostnameVerifier from the registry." },
+ "sslContextParameters": { "index": 12, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "The Camel SSL setting reference. Use the # notation to reference the SSL Context." },
+ "wrapped": { "index": 13, "kind": "parameter", "displayName": "Wrapped", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Which kind of operation that CXF endpoint producer will invoke" },
+ "lazyStartProducer": { "index": 14, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
+ "synchronous": { "index": 15, "kind": "parameter", "displayName": "Synchronous", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used" },
+ "allowStreaming": { "index": 16, "kind": "parameter", "displayName": "Allow Streaming", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the CXF component, when running in PAYLOAD mode, will DOM parse the incoming messages into DOM Elements or keep the payload as a javax.xml.transform.Source objec [...]
+ "bus": { "index": 17, "kind": "parameter", "displayName": "Bus", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.cxf.Bus", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom configured CXF Bus." },
+ "continuationTimeout": { "index": 18, "kind": "parameter", "displayName": "Continuation Timeout", "group": "advanced", "label": "advanced", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "30000", "description": "This option is used to set the CXF continuation timeout which could be used in CxfConsumer by default when the CXF server is using Jetty or Servlet transport." },
+ "cxfBinding": { "index": 19, "kind": "parameter", "displayName": "Cxf Binding", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.common.CxfBinding", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom CxfBinding to control the binding between Camel Message and CXF Message." },
+ "cxfConfigurer": { "index": 20, "kind": "parameter", "displayName": "Cxf Configurer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.jaxws.CxfConfigurer", "deprecated": false, "autowired": false, "secret": false, "description": "This option could apply the implementation of org.apache.camel.component.cxf.CxfEndpointConfigurer which supports to configure the CXF endpoint in programmatic way. User can configure [...]
+ "defaultBus": { "index": 21, "kind": "parameter", "displayName": "Default Bus", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will set the default bus when CXF endpoint create a bus by itself" },
+ "headerFilterStrategy": { "index": 22, "kind": "parameter", "displayName": "Header Filter Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HeaderFilterStrategy to filter header to and from Camel message." },
+ "mergeProtocolHeaders": { "index": 23, "kind": "parameter", "displayName": "Merge Protocol Headers", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to merge protocol headers. If enabled then propagating headers between Camel and CXF becomes more consistent and similar. For more details see CAMEL-6393." },
+ "mtomEnabled": { "index": 24, "kind": "parameter", "displayName": "Mtom Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To enable MTOM (attachments). This requires to use POJO or PAYLOAD data format mode." },
+ "properties": { "index": 25, "kind": "parameter", "displayName": "Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "properties.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "To set additional CXF options using the key\/value pairs from the Map. For example to turn on stacktraces in SOAP faults, properties.faultStackTra [...]
+ "schemaValidationEnabled": { "index": 26, "kind": "parameter", "displayName": "Schema Validation Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable schema validation for request and response. Disabled by default for performance reason" },
+ "skipPayloadMessagePartCheck": { "index": 27, "kind": "parameter", "displayName": "Skip Payload Message Part Check", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether SOAP message validation should be disabled." },
+ "loggingFeatureEnabled": { "index": 28, "kind": "parameter", "displayName": "Logging Feature Enabled", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option enables CXF Logging Feature which writes inbound and outbound SOAP messages to log." },
+ "loggingSizeLimit": { "index": 29, "kind": "parameter", "displayName": "Logging Size Limit", "group": "logging", "label": "logging", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 49152, "description": "To limit the total size of number of bytes the logger will output when logging feature has been enabled and -1 for no limit." },
+ "skipFaultLogging": { "index": 30, "kind": "parameter", "displayName": "Skip Fault Logging", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the PhaseInterceptorChain skips logging the Fault that it catches." },
+ "password": { "index": 31, "kind": "parameter", "displayName": "Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of password for the CXF client." },
+ "username": { "index": 32, "kind": "parameter", "displayName": "Username", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of username for the CXF client." },
+ "bindingId": { "index": 33, "kind": "parameter", "displayName": "Binding Id", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The bindingId for the service model to use." },
+ "portName": { "index": 34, "kind": "parameter", "displayName": "Port Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint name this service is implementing, it maps to the wsdl:portname. In the format of ns:PORT_NAME where ns is a namespace prefix valid at this scope." },
+ "publishedEndpointUrl": { "index": 35, "kind": "parameter", "displayName": "Published Endpoint Url", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can override the endpointUrl that published from the WSDL which can be accessed with service address url plus wsd" },
+ "serviceClass": { "index": 36, "kind": "parameter", "displayName": "Service Class", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "The class name of the SEI (Service Endpoint Interface) class which could have JSR181 annotation or not." },
+ "serviceName": { "index": 37, "kind": "parameter", "displayName": "Service Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The service name this service is implementing, it maps to the wsdl:servicename." },
+ "wsdlURL": { "index": 38, "kind": "parameter", "displayName": "Wsdl URL", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The location of the WSDL. Can be on the classpath, file system, or be hosted remotely." }
}
}
diff --git a/components/camel-cxf/camel-cxf-soap/pom.xml b/components/camel-cxf/camel-cxf-soap/pom.xml
index a2b18b797f20..64bd61ea550a 100644
--- a/components/camel-cxf/camel-cxf-soap/pom.xml
+++ b/components/camel-cxf/camel-cxf-soap/pom.xml
@@ -210,6 +210,12 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
diff --git a/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointConfigurer.java b/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointConfigurer.java
index 0154eb1a18da..292e6c4a15af 100644
--- a/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointConfigurer.java
+++ b/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointConfigurer.java
@@ -64,6 +64,8 @@ public class CxfEndpointConfigurer extends PropertyConfigurerSupport implements
case "mergeProtocolHeaders": target.setMergeProtocolHeaders(property(camelContext, boolean.class, value)); return true;
case "mtomenabled":
case "mtomEnabled": target.setMtomEnabled(property(camelContext, boolean.class, value)); return true;
+ case "muteexception":
+ case "muteException": target.setMuteException(property(camelContext, boolean.class, value)); return true;
case "password": target.setPassword(property(camelContext, java.lang.String.class, value)); return true;
case "portname":
case "portName": target.setPortName(property(camelContext, java.lang.String.class, value)); return true;
@@ -137,6 +139,8 @@ public class CxfEndpointConfigurer extends PropertyConfigurerSupport implements
case "mergeProtocolHeaders": return boolean.class;
case "mtomenabled":
case "mtomEnabled": return boolean.class;
+ case "muteexception":
+ case "muteException": return boolean.class;
case "password": return java.lang.String.class;
case "portname":
case "portName": return java.lang.String.class;
@@ -211,6 +215,8 @@ public class CxfEndpointConfigurer extends PropertyConfigurerSupport implements
case "mergeProtocolHeaders": return target.isMergeProtocolHeaders();
case "mtomenabled":
case "mtomEnabled": return target.isMtomEnabled();
+ case "muteexception":
+ case "muteException": return target.isMuteException();
case "password": return target.getPassword();
case "portname":
case "portName": return target.getPortName();
diff --git a/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointUriFactory.java b/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointUriFactory.java
index 09e2e6c17840..bf485db336d0 100644
--- a/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointUriFactory.java
+++ b/components/camel-cxf/camel-cxf-soap/src/generated/java/org/apache/camel/component/cxf/jaxws/CxfEndpointUriFactory.java
@@ -24,7 +24,7 @@ public class CxfEndpointUriFactory extends org.apache.camel.support.component.En
private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
private static final Map<String, String> MULTI_VALUE_PREFIXES;
static {
- Set<String> props = new HashSet<>(38);
+ Set<String> props = new HashSet<>(39);
props.add("address");
props.add("allowStreaming");
props.add("beanId");
@@ -48,6 +48,7 @@ public class CxfEndpointUriFactory extends org.apache.camel.support.component.En
props.add("loggingSizeLimit");
props.add("mergeProtocolHeaders");
props.add("mtomEnabled");
+ props.add("muteException");
props.add("password");
props.add("portName");
props.add("properties");
diff --git a/components/camel-cxf/camel-cxf-soap/src/generated/resources/META-INF/org/apache/camel/component/cxf/jaxws/cxf.json b/components/camel-cxf/camel-cxf-soap/src/generated/resources/META-INF/org/apache/camel/component/cxf/jaxws/cxf.json
index 92494c9f92ac..bf5a8ac7f9ce 100644
--- a/components/camel-cxf/camel-cxf-soap/src/generated/resources/META-INF/org/apache/camel/component/cxf/jaxws/cxf.json
+++ b/components/camel-cxf/camel-cxf-soap/src/generated/resources/META-INF/org/apache/camel/component/cxf/jaxws/cxf.json
@@ -46,39 +46,40 @@
"address": { "index": 1, "kind": "path", "displayName": "Address", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The service publish address." },
"dataFormat": { "index": 2, "kind": "parameter", "displayName": "Data Format", "group": "common", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.cxf.common.DataFormat", "enum": [ "PAYLOAD", "RAW", "MESSAGE", "CXF_MESSAGE", "POJO" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "POJO", "description": "The data type messages supported by the CXF endpoint." },
"wrappedStyle": { "index": 3, "kind": "parameter", "displayName": "Wrapped Style", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "The WSDL style that describes how parameters are represented in the SOAP body. If the value is false, CXF will chose the document-literal unwrapped style, If the value is true, CXF will chose the document- [...]
- "bridgeErrorHandler": { "index": 4, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
- "exceptionHandler": { "index": 5, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By def [...]
- "exchangePattern": { "index": 6, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "enum", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
- "cookieHandler": { "index": 7, "kind": "parameter", "displayName": "Cookie Handler", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.http.base.cookie.CookieHandler", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a cookie handler to maintain a HTTP session" },
- "defaultOperationName": { "index": 8, "kind": "parameter", "displayName": "Default Operation Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationName that will be used by the CxfProducer which invokes the remote service." },
- "defaultOperationNamespace": { "index": 9, "kind": "parameter", "displayName": "Default Operation Namespace", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationNamespace that will be used by the CxfProducer which invokes the remote service." },
- "hostnameVerifier": { "index": 10, "kind": "parameter", "displayName": "Hostname Verifier", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier", "deprecated": false, "autowired": false, "secret": false, "description": "The hostname verifier to be used. Use the # notation to reference a HostnameVerifier from the registry." },
- "sslContextParameters": { "index": 11, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "The Camel SSL setting reference. Use the # notation to reference the SSL Context." },
- "wrapped": { "index": 12, "kind": "parameter", "displayName": "Wrapped", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Which kind of operation that CXF endpoint producer will invoke" },
- "lazyStartProducer": { "index": 13, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
- "synchronous": { "index": 14, "kind": "parameter", "displayName": "Synchronous", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used" },
- "allowStreaming": { "index": 15, "kind": "parameter", "displayName": "Allow Streaming", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the CXF component, when running in PAYLOAD mode, will DOM parse the incoming messages into DOM Elements or keep the payload as a javax.xml.transform.Source objec [...]
- "bus": { "index": 16, "kind": "parameter", "displayName": "Bus", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.cxf.Bus", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom configured CXF Bus." },
- "continuationTimeout": { "index": 17, "kind": "parameter", "displayName": "Continuation Timeout", "group": "advanced", "label": "advanced", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "30000", "description": "This option is used to set the CXF continuation timeout which could be used in CxfConsumer by default when the CXF server is using Jetty or Servlet transport." },
- "cxfBinding": { "index": 18, "kind": "parameter", "displayName": "Cxf Binding", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.common.CxfBinding", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom CxfBinding to control the binding between Camel Message and CXF Message." },
- "cxfConfigurer": { "index": 19, "kind": "parameter", "displayName": "Cxf Configurer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.jaxws.CxfConfigurer", "deprecated": false, "autowired": false, "secret": false, "description": "This option could apply the implementation of org.apache.camel.component.cxf.CxfEndpointConfigurer which supports to configure the CXF endpoint in programmatic way. User can configure [...]
- "defaultBus": { "index": 20, "kind": "parameter", "displayName": "Default Bus", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will set the default bus when CXF endpoint create a bus by itself" },
- "headerFilterStrategy": { "index": 21, "kind": "parameter", "displayName": "Header Filter Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HeaderFilterStrategy to filter header to and from Camel message." },
- "mergeProtocolHeaders": { "index": 22, "kind": "parameter", "displayName": "Merge Protocol Headers", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to merge protocol headers. If enabled then propagating headers between Camel and CXF becomes more consistent and similar. For more details see CAMEL-6393." },
- "mtomEnabled": { "index": 23, "kind": "parameter", "displayName": "Mtom Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To enable MTOM (attachments). This requires to use POJO or PAYLOAD data format mode." },
- "properties": { "index": 24, "kind": "parameter", "displayName": "Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "properties.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "To set additional CXF options using the key\/value pairs from the Map. For example to turn on stacktraces in SOAP faults, properties.faultStackTra [...]
- "schemaValidationEnabled": { "index": 25, "kind": "parameter", "displayName": "Schema Validation Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable schema validation for request and response. Disabled by default for performance reason" },
- "skipPayloadMessagePartCheck": { "index": 26, "kind": "parameter", "displayName": "Skip Payload Message Part Check", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether SOAP message validation should be disabled." },
- "loggingFeatureEnabled": { "index": 27, "kind": "parameter", "displayName": "Logging Feature Enabled", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option enables CXF Logging Feature which writes inbound and outbound SOAP messages to log." },
- "loggingSizeLimit": { "index": 28, "kind": "parameter", "displayName": "Logging Size Limit", "group": "logging", "label": "logging", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 49152, "description": "To limit the total size of number of bytes the logger will output when logging feature has been enabled and -1 for no limit." },
- "skipFaultLogging": { "index": 29, "kind": "parameter", "displayName": "Skip Fault Logging", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the PhaseInterceptorChain skips logging the Fault that it catches." },
- "password": { "index": 30, "kind": "parameter", "displayName": "Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of password for the CXF client." },
- "username": { "index": 31, "kind": "parameter", "displayName": "Username", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of username for the CXF client." },
- "bindingId": { "index": 32, "kind": "parameter", "displayName": "Binding Id", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The bindingId for the service model to use." },
- "portName": { "index": 33, "kind": "parameter", "displayName": "Port Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint name this service is implementing, it maps to the wsdl:portname. In the format of ns:PORT_NAME where ns is a namespace prefix valid at this scope." },
- "publishedEndpointUrl": { "index": 34, "kind": "parameter", "displayName": "Published Endpoint Url", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can override the endpointUrl that published from the WSDL which can be accessed with service address url plus wsd" },
- "serviceClass": { "index": 35, "kind": "parameter", "displayName": "Service Class", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "The class name of the SEI (Service Endpoint Interface) class which could have JSR181 annotation or not." },
- "serviceName": { "index": 36, "kind": "parameter", "displayName": "Service Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The service name this service is implementing, it maps to the wsdl:servicename." },
- "wsdlURL": { "index": 37, "kind": "parameter", "displayName": "Wsdl URL", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The location of the WSDL. Can be on the classpath, file system, or be hosted remotely." }
+ "muteException": { "index": 4, "kind": "parameter", "displayName": "Mute Exception", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "If enabled and an Exchange failed processing on the consumer side, and the exception is not a SOAP fault the service contract declares, the SOAP fault returned to the caller won't contain the exception's [...]
+ "bridgeErrorHandler": { "index": 5, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
+ "exceptionHandler": { "index": 6, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By def [...]
+ "exchangePattern": { "index": 7, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "enum", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+ "cookieHandler": { "index": 8, "kind": "parameter", "displayName": "Cookie Handler", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.http.base.cookie.CookieHandler", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a cookie handler to maintain a HTTP session" },
+ "defaultOperationName": { "index": 9, "kind": "parameter", "displayName": "Default Operation Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationName that will be used by the CxfProducer which invokes the remote service." },
+ "defaultOperationNamespace": { "index": 10, "kind": "parameter", "displayName": "Default Operation Namespace", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option will set the default operationNamespace that will be used by the CxfProducer which invokes the remote service." },
+ "hostnameVerifier": { "index": 11, "kind": "parameter", "displayName": "Hostname Verifier", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "javax.net.ssl.HostnameVerifier", "deprecated": false, "autowired": false, "secret": false, "description": "The hostname verifier to be used. Use the # notation to reference a HostnameVerifier from the registry." },
+ "sslContextParameters": { "index": 12, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "The Camel SSL setting reference. Use the # notation to reference the SSL Context." },
+ "wrapped": { "index": 13, "kind": "parameter", "displayName": "Wrapped", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Which kind of operation that CXF endpoint producer will invoke" },
+ "lazyStartProducer": { "index": 14, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
+ "synchronous": { "index": 15, "kind": "parameter", "displayName": "Synchronous", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used" },
+ "allowStreaming": { "index": 16, "kind": "parameter", "displayName": "Allow Streaming", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the CXF component, when running in PAYLOAD mode, will DOM parse the incoming messages into DOM Elements or keep the payload as a javax.xml.transform.Source objec [...]
+ "bus": { "index": 17, "kind": "parameter", "displayName": "Bus", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.cxf.Bus", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom configured CXF Bus." },
+ "continuationTimeout": { "index": 18, "kind": "parameter", "displayName": "Continuation Timeout", "group": "advanced", "label": "advanced", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "30000", "description": "This option is used to set the CXF continuation timeout which could be used in CxfConsumer by default when the CXF server is using Jetty or Servlet transport." },
+ "cxfBinding": { "index": 19, "kind": "parameter", "displayName": "Cxf Binding", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.common.CxfBinding", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom CxfBinding to control the binding between Camel Message and CXF Message." },
+ "cxfConfigurer": { "index": 20, "kind": "parameter", "displayName": "Cxf Configurer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.cxf.jaxws.CxfConfigurer", "deprecated": false, "autowired": false, "secret": false, "description": "This option could apply the implementation of org.apache.camel.component.cxf.CxfEndpointConfigurer which supports to configure the CXF endpoint in programmatic way. User can configure [...]
+ "defaultBus": { "index": 21, "kind": "parameter", "displayName": "Default Bus", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will set the default bus when CXF endpoint create a bus by itself" },
+ "headerFilterStrategy": { "index": 22, "kind": "parameter", "displayName": "Header Filter Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HeaderFilterStrategy to filter header to and from Camel message." },
+ "mergeProtocolHeaders": { "index": 23, "kind": "parameter", "displayName": "Merge Protocol Headers", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to merge protocol headers. If enabled then propagating headers between Camel and CXF becomes more consistent and similar. For more details see CAMEL-6393." },
+ "mtomEnabled": { "index": 24, "kind": "parameter", "displayName": "Mtom Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To enable MTOM (attachments). This requires to use POJO or PAYLOAD data format mode." },
+ "properties": { "index": 25, "kind": "parameter", "displayName": "Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "properties.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "To set additional CXF options using the key\/value pairs from the Map. For example to turn on stacktraces in SOAP faults, properties.faultStackTra [...]
+ "schemaValidationEnabled": { "index": 26, "kind": "parameter", "displayName": "Schema Validation Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable schema validation for request and response. Disabled by default for performance reason" },
+ "skipPayloadMessagePartCheck": { "index": 27, "kind": "parameter", "displayName": "Skip Payload Message Part Check", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether SOAP message validation should be disabled." },
+ "loggingFeatureEnabled": { "index": 28, "kind": "parameter", "displayName": "Logging Feature Enabled", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option enables CXF Logging Feature which writes inbound and outbound SOAP messages to log." },
+ "loggingSizeLimit": { "index": 29, "kind": "parameter", "displayName": "Logging Size Limit", "group": "logging", "label": "logging", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 49152, "description": "To limit the total size of number of bytes the logger will output when logging feature has been enabled and -1 for no limit." },
+ "skipFaultLogging": { "index": 30, "kind": "parameter", "displayName": "Skip Fault Logging", "group": "logging", "label": "logging", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "This option controls whether the PhaseInterceptorChain skips logging the Fault that it catches." },
+ "password": { "index": 31, "kind": "parameter", "displayName": "Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of password for the CXF client." },
+ "username": { "index": 32, "kind": "parameter", "displayName": "Username", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "This option is used to set the basic authentication information of username for the CXF client." },
+ "bindingId": { "index": 33, "kind": "parameter", "displayName": "Binding Id", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The bindingId for the service model to use." },
+ "portName": { "index": 34, "kind": "parameter", "displayName": "Port Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint name this service is implementing, it maps to the wsdl:portname. In the format of ns:PORT_NAME where ns is a namespace prefix valid at this scope." },
+ "publishedEndpointUrl": { "index": 35, "kind": "parameter", "displayName": "Published Endpoint Url", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can override the endpointUrl that published from the WSDL which can be accessed with service address url plus wsd" },
+ "serviceClass": { "index": 36, "kind": "parameter", "displayName": "Service Class", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "The class name of the SEI (Service Endpoint Interface) class which could have JSR181 annotation or not." },
+ "serviceName": { "index": 37, "kind": "parameter", "displayName": "Service Name", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The service name this service is implementing, it maps to the wsdl:servicename." },
+ "wsdlURL": { "index": 38, "kind": "parameter", "displayName": "Wsdl URL", "group": "service", "label": "service", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The location of the WSDL. Can be on the classpath, file system, or be hosted remotely." }
}
}
diff --git a/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfConsumer.java b/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfConsumer.java
index 16b63a98c308..b636b78b3726 100644
--- a/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfConsumer.java
+++ b/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfConsumer.java
@@ -153,6 +153,7 @@ public class CxfConsumer extends DefaultConsumer implements Suspendable {
private class CxfConsumerInvoker implements Invoker {
private static final String COMPLETED = "org.apache.camel.component.cxf.jaxws.completed";
+ private static final String MUTED_FAULT_MESSAGE = "Exchange processing failed";
private final CxfEndpoint endpoint;
@@ -359,12 +360,17 @@ public class CxfConsumer extends DefaultConsumer implements Suspendable {
}
private void checkFailure(org.apache.camel.Exchange camelExchange, Exchange cxfExchange) throws Fault {
- final Throwable t = extractThrowable(camelExchange);
+ // an exception set on the exchange is a route failure; one carried in the body is a fault the route
+ // chose to return, and stays part of the contract either way
+ final Throwable routeFailure = camelExchange.getException();
+ final Throwable t = routeFailure != null ? routeFailure : extractFromBody(camelExchange, null);
if (t != null) {
cxfExchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
if (t instanceof Fault fault) {
handleFault(cxfExchange, fault);
+ } else if (routeFailure != null && isMuted(t)) {
+ buildFaultFromThrowable(mutedThrowable());
} else {
// This is not a CXF Fault. Build the CXF Fault manually.
buildFaultFromThrowable(t);
@@ -373,6 +379,26 @@ public class CxfConsumer extends DefaultConsumer implements Suspendable {
}
}
+ /**
+ * Only an <em>undeclared</em> route failure is muted. An exception the service contract declares - annotated
+ * {@code @WebFault} - is what a SOAP client is written against, so suppressing it would break the contract
+ * rather than protect anything.
+ */
+ private boolean isMuted(Throwable t) {
+ return ((CxfEndpoint) getEndpoint()).isMuteException()
+ && t.getClass().getAnnotation(WebFault.class) == null;
+ }
+
+ /**
+ * Carries no class name, no message and no stack trace of the route's exception: CXF copies the message into
+ * the SOAP faultstring, and can be configured to put the stack trace in the fault detail.
+ */
+ private static Throwable mutedThrowable() {
+ Exception muted = new Exception(MUTED_FAULT_MESSAGE);
+ muted.setStackTrace(new StackTraceElement[0]);
+ return muted;
+ }
+
private static void buildFaultFromThrowable(Throwable t) {
Fault fault = new Fault(t);
if (fault.getMessage() == null) {
@@ -410,15 +436,9 @@ public class CxfConsumer extends DefaultConsumer implements Suspendable {
throw t;
}
- private static Throwable extractThrowable(org.apache.camel.Exchange camelExchange) {
- Throwable t = camelExchange.getException();
- if (t == null) {
- // SOAP faults can be stored as exceptions as message body (to be backwards compatible)
- t = extractFromBody(camelExchange, t);
- }
- return t;
- }
-
+ /**
+ * SOAP faults can be stored as exceptions as message body (to be backwards compatible).
+ */
private static Throwable extractFromBody(org.apache.camel.Exchange camelExchange, Throwable t) {
Object body = camelExchange.getMessage().getBody();
if (body instanceof Throwable throwable) {
diff --git a/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java b/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java
index 3c68352c8dd7..3deb088a40d4 100644
--- a/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java
+++ b/components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java
@@ -203,6 +203,8 @@ public class CxfEndpoint extends DefaultEndpoint implements AsyncEndpoint, Heade
private boolean skipPayloadMessagePartCheck;
@UriParam(label = "logging")
private boolean skipFaultLogging;
+ @UriParam(label = "consumer", defaultValue = "true")
+ private boolean muteException = true;
@UriParam(label = "advanced")
private boolean mergeProtocolHeaders;
@UriParam(label = "advanced")
@@ -1458,6 +1460,20 @@ public class CxfEndpoint extends DefaultEndpoint implements AsyncEndpoint, Heade
this.skipFaultLogging = skipFaultLogging;
}
+ public boolean isMuteException() {
+ return muteException;
+ }
+
+ /**
+ * If enabled and an Exchange failed processing on the consumer side, and the exception is not a SOAP fault the
+ * service contract declares, the SOAP fault returned to the caller won't contain the exception's class or message.
+ * Faults the route raises deliberately - a CXF {@code Fault}, an exception annotated {@code @WebFault}, or a
+ * {@code Throwable} set as the message body - are part of the contract and are always returned in full.
+ */
+ public void setMuteException(boolean muteException) {
+ this.muteException = muteException;
+ }
+
public boolean isMergeProtocolHeaders() {
return mergeProtocolHeaders;
}
diff --git a/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerContinuationTimeoutTest.java b/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerContinuationTimeoutTest.java
index da7c70a50440..8c505d3a9175 100644
--- a/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerContinuationTimeoutTest.java
+++ b/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerContinuationTimeoutTest.java
@@ -62,42 +62,45 @@ public class CxfConsumerContinuationTimeoutTest extends CamelTestSupport {
.setBody(constant("Sensitive Data"))
.to(simpleEndpointURI + "&continuationTimeout=5000&dataFormat=RAW");
- from(simpleEndpointURI + "&continuationTimeout=5000&dataFormat=RAW").process(new AsyncProcessorSupport() {
- @Override
- public boolean process(Exchange exchange, AsyncCallback asyncCallback) {
- Message in = exchange.getIn();
- // check the content-length header is filtered
- Object value = in.getHeader("Content-Length");
- assertNull(value, "The Content-Length header should be removed");
- // Get the request message
- String request = in.getBody(String.class);
- String priority = in.getHeader("priority", "fast", String.class);
-
- // need not to block this thread to simulate slow response so use a thread pool to wait
- if ("slow".equalsIgnoreCase(priority)) {
- pool.submit(() -> {
- try {
- log.info("Sleeping for 10 seconds to simulate slow response");
- Thread.sleep(10000);
- } catch (InterruptedException e) {
- // ignore
- } finally {
- asyncCallback.done(false);
+ // muteException=false: these tests assert the continuation-timeout message reaches the caller,
+ // which CAMEL-24477 otherwise replaces with a generic fault
+ from(simpleEndpointURI + "&continuationTimeout=5000&dataFormat=RAW&muteException=false")
+ .process(new AsyncProcessorSupport() {
+ @Override
+ public boolean process(Exchange exchange, AsyncCallback asyncCallback) {
+ Message in = exchange.getIn();
+ // check the content-length header is filtered
+ Object value = in.getHeader("Content-Length");
+ assertNull(value, "The Content-Length header should be removed");
+ // Get the request message
+ String request = in.getBody(String.class);
+ String priority = in.getHeader("priority", "fast", String.class);
+
+ // need not to block this thread to simulate slow response so use a thread pool to wait
+ if ("slow".equalsIgnoreCase(priority)) {
+ pool.submit(() -> {
+ try {
+ log.info("Sleeping for 10 seconds to simulate slow response");
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ // ignore
+ } finally {
+ asyncCallback.done(false);
+ }
+ });
+ return false;
+ } else {
+ // Send the response message back
+ if (request.indexOf(ECHO_METHOD) > 0) {
+ exchange.getMessage().setBody(ECHO_RESPONSE);
+ } else { // echoBoolean call
+ exchange.getMessage().setBody(ECHO_BOOLEAN_RESPONSE);
+ }
}
- });
- return false;
- } else {
- // Send the response message back
- if (request.indexOf(ECHO_METHOD) > 0) {
- exchange.getMessage().setBody(ECHO_RESPONSE);
- } else { // echoBoolean call
- exchange.getMessage().setBody(ECHO_BOOLEAN_RESPONSE);
+ asyncCallback.done(true);
+ return true;
}
- }
- asyncCallback.done(true);
- return true;
- }
- });
+ });
}
};
}
diff --git a/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerMuteExceptionTest.java b/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerMuteExceptionTest.java
new file mode 100644
index 000000000000..d9c964b3d870
--- /dev/null
+++ b/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerMuteExceptionTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.cxf.jaxws;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cxf.common.CXFTestSupport;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.apache.cxf.frontend.ClientFactoryBean;
+import org.apache.cxf.greeter_control.Greeter;
+import org.apache.cxf.greeter_control.PingMeFault;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+/**
+ * The consumer used to put the route exception's message into the SOAP fault returned to the caller, so any
+ * remote-triggerable failure handed the caller internal detail.
+ * <p>
+ * {@code muteException} defaults to true, matching the http consumers aligned by CAMEL-23651. It applies only to
+ * <em>undeclared</em> failures: an exception the service contract declares with {@code @WebFault} is what a SOAP client
+ * is written against, so it is still returned in full.
+ */
+class CxfConsumerMuteExceptionTest extends CamelTestSupport {
+
+ private static final String DETAIL = "the-internal-detail-a-caller-must-not-see";
+
+ private static final String MUTED_ADDRESS
+ = "http://localhost:" + CXFTestSupport.getPort1() + "/CxfConsumerMuteExceptionTest/muted";
+ private static final String UNMUTED_ADDRESS
+ = "http://localhost:" + CXFTestSupport.getPort2() + "/CxfConsumerMuteExceptionTest/unmuted";
+ private static final String DECLARED_ADDRESS
+ = "http://localhost:" + CXFTestSupport.getPort3() + "/CxfConsumerMuteExceptionTest/declared";
+
+ private static final String SERVICE_CLASS = "serviceClass=org.apache.cxf.greeter_control.Greeter";
+
+ @Test
+ void anUndeclaredFailureIsNotDescribedToTheCaller() {
+ assertThatThrownBy(() -> client(MUTED_ADDRESS).pingMe())
+ .as("the SOAP fault must carry neither the class nor the message of the route's exception")
+ .hasMessageNotContaining(DETAIL)
+ .hasMessageNotContaining("IllegalStateException");
+ }
+
+ @Test
+ void muteExceptionFalseDescribesTheFailureAsBefore() {
+ assertThatThrownBy(() -> client(UNMUTED_ADDRESS).pingMe())
+ .hasMessageContaining(DETAIL);
+ }
+
+ /**
+ * The guarantee that makes muting safe to default on: a fault the WSDL declares is part of the contract, so muting
+ * must not touch it. Without this carve-out every SOAP client written against a declared fault would break.
+ */
+ @Test
+ void aDeclaredWebFaultIsStillReturnedInFullWhileMuted() {
+ assertThatThrownBy(() -> client(DECLARED_ADDRESS).pingMe())
+ .isInstanceOf(PingMeFault.class)
+ .hasMessageContaining(DETAIL);
+ }
+
+ @Test
+ void muteExceptionDefaultsToTrue() {
+ CxfEndpoint endpoint = context.getEndpoint("cxf://" + MUTED_ADDRESS + "?" + SERVICE_CLASS, CxfEndpoint.class);
+ assertThat(endpoint.isMuteException()).isTrue();
+ }
+
+ private static Greeter client(String address) {
+ JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
+ ClientFactoryBean clientBean = proxyFactory.getClientFactoryBean();
+ clientBean.setAddress(address);
+ clientBean.setServiceClass(Greeter.class);
+ return (Greeter) proxyFactory.create();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("cxf://" + MUTED_ADDRESS + "?" + SERVICE_CLASS)
+ .process(e -> {
+ throw new IllegalStateException(DETAIL);
+ });
+ from("cxf://" + UNMUTED_ADDRESS + "?" + SERVICE_CLASS + "&muteException=false")
+ .process(e -> {
+ throw new IllegalStateException(DETAIL);
+ });
+ from("cxf://" + DECLARED_ADDRESS + "?" + SERVICE_CLASS)
+ .process(e -> {
+ throw new PingMeFault(DETAIL);
+ });
+ }
+ };
+ }
+}
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index 74b7f414031b..f73ec650e792 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -689,6 +689,38 @@ Deployments whose introspection endpoint omits `iss` must either have it include
`validateIssuer` off. The locally verified JWT path is unaffected — it uses Keycloak's own
`TokenVerifier.RealmUrlCheck`.
+=== camel-cxf
+
+The CXF consumer no longer describes an undeclared route failure in the SOAP fault returned to the caller.
+
+When a route consuming from `cxf:` failed with an exception the service contract does not declare, the
+exception's message — or its class name, when it had no message — became the SOAP `faultstring`. A new
+`muteException` consumer option controls this, and it defaults to `true`, the same default the HTTP
+consumers carry (`camel-http-common` and therefore `camel-servlet` and `camel-jetty`, plus `camel-http`,
+`camel-platform-http`, and `camel-netty-http` and `camel-undertow` since 4.21.0).
+
+Muting applies **only to undeclared failures**. Faults the route raises deliberately are part of the
+service contract and are still returned in full:
+
+* a CXF `Fault` or `SoapFault` thrown by the route,
+* an exception annotated `@WebFault` (a fault the WSDL declares),
+* a `Throwable` or a `CxfPayload` carrying a `<soap:Fault>` set as the message body.
+
+Only an exception that reaches `Exchange.getException()` without a `@WebFault` annotation is replaced,
+by a fault reading `Exchange processing failed`.
+
+Note that this includes framework failures, not just route exceptions. In particular, a `continuationTimeout`
+expiry previously returned `The OUT message was not received within: 5000 millis.` to the caller and now
+returns the generic fault; set `muteException=false` on that endpoint if the timeout detail is relied upon
+for diagnostics.
+
+A route that relies on an undeclared exception's message reaching the caller must opt back in explicitly:
+
+[source,text]
+----
+cxf://http://localhost:8080/service?serviceClass=com.example.MyService&muteException=false
+----
+
=== camel-thrift
The `thrift` data format used to deserialize into its own `defaultInstance` and return that object to
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CxfEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CxfEndpointBuilderFactory.java
index f0c09a1c0cad..63ecb3b889b1 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CxfEndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CxfEndpointBuilderFactory.java
@@ -113,6 +113,48 @@ public interface CxfEndpointBuilderFactory {
doSetProperty("wrappedStyle", wrappedStyle);
return this;
}
+ /**
+ * If enabled and an Exchange failed processing on the consumer side,
+ * and the exception is not a SOAP fault the service contract declares,
+ * the SOAP fault returned to the caller won't contain the exception's
+ * class or message. Faults the route raises deliberately - a CXF Fault,
+ * an exception annotated {code WebFault}, or a Throwable set as the
+ * message body - are part of the contract and are always returned in
+ * full.
+ *
+ * The option is a: <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: consumer
+ *
+ * @param muteException the value to set
+ * @return the dsl builder
+ */
+ default CxfEndpointConsumerBuilder muteException(boolean muteException) {
+ doSetProperty("muteException", muteException);
+ return this;
+ }
+ /**
+ * If enabled and an Exchange failed processing on the consumer side,
+ * and the exception is not a SOAP fault the service contract declares,
+ * the SOAP fault returned to the caller won't contain the exception's
+ * class or message. Faults the route raises deliberately - a CXF Fault,
+ * an exception annotated {code WebFault}, or a Throwable set as the
+ * message body - are part of the contract and are always returned in
+ * full.
+ *
+ * The option will be converted to a <code>boolean</code> type.
+ *
+ * Default: true
+ * Group: consumer
+ *
+ * @param muteException the value to set
+ * @return the dsl builder
+ */
+ default CxfEndpointConsumerBuilder muteException(String muteException) {
+ doSetProperty("muteException", muteException);
+ return this;
+ }
/**
* This option enables CXF Logging Feature which writes inbound and
* outbound SOAP messages to log.