Apache Camel 如何将 SOAP 消息从 JMS 队列传递到 CXF 端点
Apache Camel How to pass SOAP message from JMS queue to CXF endpoint
我正在尝试创建一个 Camel 路线,它将:
- 从队列中获取JMS消息,消息体为SOAP请求。
- 将消息发送到 cxf 端点。
- 将响应放入响应队列。
这是我的代码:
private void setupRequestRoute() {
from("jms:queue:input")
.setHeader(CxfConstants.OPERATION_NAME, simple("XXXXXX"))
.setHeader(CxfConstants.OPERATION_NAMESPACE, simple("XXXXXX"))
.log("Route headers : ${headers}")
.to("cxf:bean:myEndpoint")
.to("jms:queue:response")
.end();
}
端点配置:
<cxf:cxfEndpoint id="myServiceEndpoint"
address="http://localhost:8080/MyService/V2"
wsdlURL="schemas/MyService.wsdl"
xmlns:c="http://xxxx.xxxx/xxxxxxxx/XXX/MyService/V2">
<cxf:outFaultInterceptors>
<ref bean="interceptor.out.soap.fault"/>
</cxf:outFaultInterceptors>
<cxf:properties>
<entry key="schema-validation-enabled" value="true" />
<entry key="dataFormat" value="PAYLOAD" />
<entry key="defaultBus" value="true" />
<entry key="allowStreaming" value="false" />
</cxf:properties>
</cxf:cxfEndpoint>
我觉得我误解了骆驼在这种情况下工作的一些基本原理。似乎是肥皂信封的存在导致了这个问题。我曾假设 camel 能够获取原始 soap 消息并将其转换为 cxf 端点的正确消息格式。
有人可以向我解释如何将 SOAP 请求传递到 CXF 端点吗?
2018-12-03 12:27:32,222 | ERROR | INPUT] | DefaultErrorHandler | 43 - org.apache.camel.camel-core - 2.16.4 | Failed delivery for (MessageId: ID:xxxxxxxxxxxx-46588-1543829293785-1:21:1:1:1
on ExchangeId: ID-xxxxxxxxxxxx-35264-1543835233229-2-1). Exhausted after delivery attempt: 1 caught: java.lang.IllegalArgumentException: The PayLoad elements cannot fit with the message parts of the BindingOpera
tion. Please check the BindingOperation and PayLoadMessage.
Message History
---------------------------------------------------------------------------------------------------------------------------------------
RouteId ProcessorId Processor Elapsed (ms)
[from.XS.to.xsb?dat] [from.XS.to.xsb?dat] [jms://queue:input ] [ 17]
[from.XS.to.xsb?dat] [setHeader7 ] [setHeader[operationName] ] [ 0]
[from.XS.to.xsb?dat] [setHeader8 ] [setHeader[operationNamespace] ] [ 0]
[from.XS.to.xsb?dat] [log6 ] [log ] [ 12]
[from.XS.to.xsb?dat] [to45 ] [cxf:bean:myEndpoint ] [ 3]
Exchange
---------------------------------------------------------------------------------------------------------------------------------------
Exchange[
Id ID-xxxxxxxxxxxx-35264-1543835233229-2-1
ExchangePattern InOut
Headers {breadcrumbId=ID:xxxxxxxxxxxx-46588-1543829293785-1:21:1:1:1, CamelRedelivered=false, CamelRedeliveryCounter=0, JMSCorrelationID=null, JMSCorrelationIDAsBytes=null, JMSDeliveryMode=2,
JMSDestination=queue://input, JMSExpiration=0, JMSMessageID=ID:xxxxxxxxxxxx-46588-1543829293785-1:21:1:1:1, JMSPriority=4, JMSRedelivered=false, JMSReplyTo=queue://response, JMSTimestamp=1543840052184, JMSType=null, JMSXGroupID=null, JMSXUserID=null, operationName=MyOperation, operationNamespace=MyOperationNameSpace}
BodyType String
Body <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://xxxx.xxxx/xxxxxxxx/xxx/xxxxxxxxxxxxxxxxxx/V2" xmlns:v21="http://xxxx.xxxx/xxxxxxxx/xxx/xxxxxx/V2">
<soapenv:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecur
ity-utility-1.0.xsd"><wsse:UsernameToken wsu:Id="UsernameToken-xxxx"><wsse:Username>username</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-ws
s-username-token-profile-1.0#PasswordDigest">xxxx</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
xxxxx</wsse:Nonce><wsu:Created>2018-12-03T12:27:32.183Z</wsu:Created></wsse:UsernameToken></wsse:Security></soapenv:Header> <soapenv:Body> <v2:MyRequest>
...
...
</v2:MyRequest> </soapenv:Body></soapenv:Envelope>
]
Stacktrace
Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
java.lang.IllegalArgumentException: The PayLoad elements cannot fit with the message parts of the BindingOperation. Please check the BindingOperation and PayLoadMessage.
at org.apache.camel.component.cxf.CxfEndpoint$CamelCxfClientImpl.setParameters(CxfEndpoint.java:1189)[44:org.apache.camel.camel-cxf:2.16.4]
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:470)[57:org.apache.cxf.cxf-core:3.1.5]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:416)[57:org.apache.cxf.cxf-core:3.1.5]
at org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:134)[44:org.apache.camel.camel-cxf:2.16.4]
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:196)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:196)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:91)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:112)[46:org.apache.camel.camel-jms:2.16.4]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:555)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:515)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:485)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1103)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1095)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:992)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)[:1.8.0_181]
at java.lang.Thread.run(Thread.java:748)[:1.8.0_181]
你指定了PAYLOAD
数据格式,但是按照docs即为soap:body
处理。您能否将 body 的 XPath 输出到当前交换中,或者您是否需要所有 WSE headers?
或尝试其他数据格式之一 MESSAGE
(我认为在更高版本中称为 RAW
?)或 CXF_MESSAGE
听起来它们更接近您想要的实现。
我正在尝试创建一个 Camel 路线,它将:
- 从队列中获取JMS消息,消息体为SOAP请求。
- 将消息发送到 cxf 端点。
- 将响应放入响应队列。
这是我的代码:
private void setupRequestRoute() {
from("jms:queue:input")
.setHeader(CxfConstants.OPERATION_NAME, simple("XXXXXX"))
.setHeader(CxfConstants.OPERATION_NAMESPACE, simple("XXXXXX"))
.log("Route headers : ${headers}")
.to("cxf:bean:myEndpoint")
.to("jms:queue:response")
.end();
}
端点配置:
<cxf:cxfEndpoint id="myServiceEndpoint"
address="http://localhost:8080/MyService/V2"
wsdlURL="schemas/MyService.wsdl"
xmlns:c="http://xxxx.xxxx/xxxxxxxx/XXX/MyService/V2">
<cxf:outFaultInterceptors>
<ref bean="interceptor.out.soap.fault"/>
</cxf:outFaultInterceptors>
<cxf:properties>
<entry key="schema-validation-enabled" value="true" />
<entry key="dataFormat" value="PAYLOAD" />
<entry key="defaultBus" value="true" />
<entry key="allowStreaming" value="false" />
</cxf:properties>
</cxf:cxfEndpoint>
我觉得我误解了骆驼在这种情况下工作的一些基本原理。似乎是肥皂信封的存在导致了这个问题。我曾假设 camel 能够获取原始 soap 消息并将其转换为 cxf 端点的正确消息格式。
有人可以向我解释如何将 SOAP 请求传递到 CXF 端点吗?
2018-12-03 12:27:32,222 | ERROR | INPUT] | DefaultErrorHandler | 43 - org.apache.camel.camel-core - 2.16.4 | Failed delivery for (MessageId: ID:xxxxxxxxxxxx-46588-1543829293785-1:21:1:1:1
on ExchangeId: ID-xxxxxxxxxxxx-35264-1543835233229-2-1). Exhausted after delivery attempt: 1 caught: java.lang.IllegalArgumentException: The PayLoad elements cannot fit with the message parts of the BindingOpera
tion. Please check the BindingOperation and PayLoadMessage.
Message History
---------------------------------------------------------------------------------------------------------------------------------------
RouteId ProcessorId Processor Elapsed (ms)
[from.XS.to.xsb?dat] [from.XS.to.xsb?dat] [jms://queue:input ] [ 17]
[from.XS.to.xsb?dat] [setHeader7 ] [setHeader[operationName] ] [ 0]
[from.XS.to.xsb?dat] [setHeader8 ] [setHeader[operationNamespace] ] [ 0]
[from.XS.to.xsb?dat] [log6 ] [log ] [ 12]
[from.XS.to.xsb?dat] [to45 ] [cxf:bean:myEndpoint ] [ 3]
Exchange
---------------------------------------------------------------------------------------------------------------------------------------
Exchange[
Id ID-xxxxxxxxxxxx-35264-1543835233229-2-1
ExchangePattern InOut
Headers {breadcrumbId=ID:xxxxxxxxxxxx-46588-1543829293785-1:21:1:1:1, CamelRedelivered=false, CamelRedeliveryCounter=0, JMSCorrelationID=null, JMSCorrelationIDAsBytes=null, JMSDeliveryMode=2,
JMSDestination=queue://input, JMSExpiration=0, JMSMessageID=ID:xxxxxxxxxxxx-46588-1543829293785-1:21:1:1:1, JMSPriority=4, JMSRedelivered=false, JMSReplyTo=queue://response, JMSTimestamp=1543840052184, JMSType=null, JMSXGroupID=null, JMSXUserID=null, operationName=MyOperation, operationNamespace=MyOperationNameSpace}
BodyType String
Body <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://xxxx.xxxx/xxxxxxxx/xxx/xxxxxxxxxxxxxxxxxx/V2" xmlns:v21="http://xxxx.xxxx/xxxxxxxx/xxx/xxxxxx/V2">
<soapenv:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecur
ity-utility-1.0.xsd"><wsse:UsernameToken wsu:Id="UsernameToken-xxxx"><wsse:Username>username</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-ws
s-username-token-profile-1.0#PasswordDigest">xxxx</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
xxxxx</wsse:Nonce><wsu:Created>2018-12-03T12:27:32.183Z</wsu:Created></wsse:UsernameToken></wsse:Security></soapenv:Header> <soapenv:Body> <v2:MyRequest>
...
...
</v2:MyRequest> </soapenv:Body></soapenv:Envelope>
]
Stacktrace
Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
java.lang.IllegalArgumentException: The PayLoad elements cannot fit with the message parts of the BindingOperation. Please check the BindingOperation and PayLoadMessage.
at org.apache.camel.component.cxf.CxfEndpoint$CamelCxfClientImpl.setParameters(CxfEndpoint.java:1189)[44:org.apache.camel.camel-cxf:2.16.4]
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:470)[57:org.apache.cxf.cxf-core:3.1.5]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:416)[57:org.apache.cxf.cxf-core:3.1.5]
at org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:134)[44:org.apache.camel.camel-cxf:2.16.4]
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:196)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:196)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:91)[43:org.apache.camel.camel-core:2.16.4]
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:112)[46:org.apache.camel.camel-jms:2.16.4]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:555)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:515)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:485)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1103)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1095)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:992)[154:org.apache.servicemix.bundles.spring-jms:3.2.17.RELEASE_1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)[:1.8.0_181]
at java.lang.Thread.run(Thread.java:748)[:1.8.0_181]
你指定了PAYLOAD
数据格式,但是按照docs即为soap:body
处理。您能否将 body 的 XPath 输出到当前交换中,或者您是否需要所有 WSE headers?
或尝试其他数据格式之一 MESSAGE
(我认为在更高版本中称为 RAW
?)或 CXF_MESSAGE
听起来它们更接近您想要的实现。