Reputation: 8311
I have a main flow which is exposing a webservice :-
<flow name="ServiceFlow" doc:name="ServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>
<cxf:jaxws-service serviceClass="com.test.services.schema.maindata.v1.MainData" doc:name="SOAP"/>
<component class="com.test.services.schema.maindata.v1.Impl.MainDataImpl" doc:name="JavaMain_ServiceImpl"/>
</flow>
Now I have another flow which is a proxy flow to this main flow :-
<flow name="ProxyFlow" doc:name="ProxyFlow" processingStrategy="synchronous">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="8086" path="proxy/mainData" doc:name="HTTP" />
<!-- This is for SOAP Request validation -->
<message-filter onUnaccepted="ValidationFailFlow" doc:name="filter to validate xml against xsd" throwOnUnaccepted="true" >
<mulexml:is-xml-filter />
</message-filter>
<!-- ends -->
<cxf:proxy-service namespace="http://services.test.com/schema/MainData/V1" service="MainData" payload="envelope" wsdlLocation="MainData.wsdl" doc:name="SOAP"/>
<cxf:proxy-client payload="envelope"
doc:name="SOAP" />
<http:outbound-endpoint exchange-pattern="request-response"
host="localhost" port="8082" path="mainData" method="POST" doc:name="HTTP" />
</flow>
<!-- This sub flow contains the message that need to be displayed in case of validation fails from validation filter -->
<sub-flow name="ValidationFailFlow" doc:name="ValidationFailFlow">
<logger message="SOAP Request is not valid!!" level="INFO" doc:name="Logger"/>
<set-payload value="SOAP Request is not valid .... Message has been rejected by filter." doc:name="Set Payload"/>
</sub-flow>
<!-- ends -->
Now the issue is ... Since I have used a validation filter <mulexml:is-xml-filter />
in Proxy flow the webservice request is getting validated .. but in this case, a valid SOAP request is throwing exception... for example .. the following SOAP request is valid :-
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://services.test.com/schema/MainData/V1">
<soapenv:Header/>
<soapenv:Body>
<v1:insertDataRequest>
<v1:Id>55</v1:Id>
<v1:Name>ghghg</v1:Name>
<v1:Age>666</v1:Age>
<v1:Designation>hghghgh</v1:Designation>
</v1:insertDataRequest>
</soapenv:Body>
</soapenv:Envelope>
But it is throwing following exception :-
java.lang.RuntimeException: Couldn't parse stream.
at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1262)
at org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:105)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:122)
at org.mule.module.cxf.CxfInboundMessageProcessor.sendToDestination(CxfInboundMessageProcessor.java:338)
at org.mule.module.cxf.CxfInboundMessageProcessor.process(CxfInboundMessageProcessor.java:144)
at org.mule.module.cxf.config.FlowConfiguringMessageProcessor.process(FlowConfiguringMessageProcessor.java:48)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
Caused by: com.ctc.wstx.exc.WstxIOException: Attempted read from closed stream.
at com.ctc.wstx.stax.WstxInputFactory.doCreateSR(WstxInputFactory.java:536)
at com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:585)
at com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:610)
at com.ctc.wstx.stax.WstxInputFactory.createXMLStreamReader(WstxInputFactory.java:316)
at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1260)
... 97 more
Caused by: java.io.IOException: Attempted read from closed stream.
at org.apache.commons.httpclient.ContentLengthInputStream.read(ContentLengthInputStream.java:160)
at com.ctc.wstx.io.BaseReader.readBytes(BaseReader.java:155)
at com.ctc.wstx.io.UTF8Reader.loadMore(UTF8Reader.java:368)
at com.ctc.wstx.io.UTF8Reader.read(UTF8Reader.java:111)
at com.ctc.wstx.io.ReaderBootstrapper.initialLoad(ReaderBootstrapper.java:250)
at com.ctc.wstx.io.ReaderBootstrapper.bootstrapInput(ReaderBootstrapper.java:133)
at com.ctc.wstx.stax.WstxInputFactory.doCreateSR(WstxInputFactory.java:531)
... 101 more
And following SOAP response :-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Couldn't parse stream.</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Please help ... How can I use <mulexml:is-xml-filter />
for validating SOAP request and what does the exception means for a valid SOAP request ???
Upvotes: 1
Views: 1256
Reputation: 705
The problem is that the filter consumes the stream thus the cxf proxy service do not have any data to work with.
Add a object to string transformer before the filter to load the request into memory. Then it can be reread by the cxf proxy service.
Something like this:
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="8086" path="proxy/mainData" doc:name="HTTP" />
<!-- Transform to String so we can reread the payload multiple times -->
<object-to-string-transformer />
<!-- This is for SOAP Request validation -->
<message-filter onUnaccepted="ValidationFailFlow" doc:name="filter to validate xml against xsd" throwOnUnaccepted="true" >
<mulexml:is-xml-filter />
</message-filter>
<!-- ends -->
Upvotes: 2