Anirban Sen Chowdhary
Anirban Sen Chowdhary

Reputation: 8321

How to use Mule schema-validation-filter for validating SOAP Request

I was exploring Mule schema-validation-filter which is used to validate XML input against a xsd schema.... I have no Idea how to implement this schema-validation-filter... I thought of using it against a incoming SOAP request for a web service .. So, I have the following approach to validate a SOAP request :-

 <mulexml:schema-validation-filter name="Schema_Validation" schemaLocations="MainData.xsd" returnResult="true" doc:name="Schema Validation" />  

<flow name="ServiceFlow" doc:name="ServiceFlow">

<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>

   <async doc:name="Async">
            <mulexml:object-to-xml-transformer doc:name="Object to XML"/>
            <message-filter  doc:name="filter to validate xml against xsd" throwOnUnaccepted="true" >
                <filter ref="Schema_Validation"/>
            </message-filter>

            <logger message="Doneeeeee" level="DEBUG" doc:name="Logger"/>
        </async>  

<cxf:jaxws-service  validationEnabled="true" 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> 

But whenever I test the service using SOAP UI I get the following exception :-

Root Exception stack trace:
org.mule.api.routing.filter.FilterUnacceptedException: Message has been rejected by filter. Message payload is of type: DocumentImpl
    at org.mule.routing.MessageFilter.filterUnacceptedException(MessageFilter.java:96)
    at org.mule.processor.AbstractFilteringMessageProcessor.handleUnaccepted(AbstractFilteringMessageProcessor.java:58)
    at org.mule.processor.AbstractFilteringMessageProcessor.process(AbstractFilteringMessageProcessor.java:44)
    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)
    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)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
    at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:51)
    at org.mule.processor.AsyncInterceptingMessageProcessor.processNextTimed(AsyncInterceptingMessageProcessor.java:118)
    at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:189)
    at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:182)
    at org.mule.execution.ExecuteCallbackInterceptor.execute(ExecuteCallbackInterceptor.java:16)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:30)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:14)
    at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:54)
    at org.mule.execution.ResolvePreviousTransactionInterceptor.execute(ResolvePreviousTransactionInterceptor.java:44)
    at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:50)
    at org.mule.execution.ValidateTransactionalStateInterceptor.execute(ValidateTransactionalStateInterceptor.java:40)
    at org.mule.execution.IsolateCurrentTransactionInterceptor.execute(IsolateCurrentTransactionInterceptor.java:41)
    at org.mule.execution.ExternalTransactionInterceptor.execute(ExternalTransactionInterceptor.java:48)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:28)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:13)
    at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:109)
    at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:30)
    at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker.doRun(AsyncInterceptingMessageProcessor.java:181)
    at org.mule.work.AbstractMuleEventWork.run(AbstractMuleEventWork.java:39)
    at org.mule.work.WorkerContext.run(WorkerContext.java:286)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)

I tried to search over internet to find a suitable approach to validate the SOAP request and use this schema-validation-filter .. but didn't find a solution... Please help me and let me know is this the correct way I am doing to validate a SOAP Request .. What type of data format does the filter expect ?? and how to make it working ?

Updated flow :-

<mulexml:schema-validation-filter name="Schema_Validation" schemaLocations="MainData.xsd" returnResult="true" doc:name="Schema Validation" />  

<flow name="ServiceFlow" doc:name="ServiceFlow">

<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>


            <mulexml:object-to-xml-transformer doc:name="Object to XML"/>
            <message-filter  doc:name="filter to validate xml against xsd" throwOnUnaccepted="true" >
                <filter ref="Schema_Validation"/>
            </message-filter>

<cxf:jaxws-service  validationEnabled="true" 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> 

Updated the flow by removing async block ... but still gets the same exception :- Message has been rejected by filter. Message payload is of type: DocumentImpl

Upvotes: 1

Views: 3429

Answers (3)

Anirban Sen Chowdhary
Anirban Sen Chowdhary

Reputation: 8321

So, finally as David suggested, the solution is to make sure the XSD contains SOAP envelope ... So I added the following and it worked for me :-

<import namespace="http://schemas.xmlsoap.org/soap/envelope/"   
            schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"></import>

reference :- How to fix soapenv:Envelope issue in XSD schema while validating with SOAP request/response

Upvotes: 0

tortoise
tortoise

Reputation: 613

I advise you to use

<mulexml:dom-to-xml-transformer />

instead of object-to-xml transformer you are using here. Log the entire mule message before your filter to make sure you are not sending a documentImpl object to the filter. After using dom-to-xml it should be a string.

Try this:

<http:inbound-endpoint address="http://localhost:9002/test">
  <cxf:proxy-service />
</http:inbound-endpoint>

<mulexml:dom-to-xml-transformer />
<logger level="INFO" message=""/>
<message-filter  doc:name="filter to validate xml against xsd"  throwOnUnaccepted="true">
            <filter ref="Schema_Validation"/>
        </message-filter>

This cxf:proxy-service takes out the contents of soapenv:body and assigns it to the payload variable of mule message. Hence, the schema filter would be able to validate your payload without soap envelope and headers.

Upvotes: 2

David Dossot
David Dossot

Reputation: 33413

Normally having cxf:jaxws-service validationEnabled="true" should be enough. Are you saying this doesn't validate the SOAP body?

Also, if you want to manually validate requests:

  • Don't do it async: what's the point of validating if you do it on the side and don't actually break the request in case of error?
  • Make sure the XSD you use for validation validates the whole SOAP envelope, not just the body.

Upvotes: 0

Related Questions