Tuesday, July 19, 2022

How to disable Apache CXF policy engine on CXF client side (Notes to myself)

Recently I came across a case where a JAX-WS service provided WSDL with lots of Policies but didn't actually enforce them. 
This was causing API to be consumed correctly via Postman but not from Apache CXF wsclient as it was trying to enforce the policies. 
After doing lot of efforts I ended up creating the dummy server for testing using WSDL2Java and recreate the scenario as the external service wasn't in my control. 

Once I did this and tested against the Dummy service first thing I got was behavior change where even the pure HTTP request from postman started failing with same policy related soap fault. 

After log of searching and trial and error found out on server side turning off policy engine gave me the same behavior as external Service which is passing on Postman and failing with Apache CXF wsclient. To Switch off the server side policy engine I added :
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:cxf="http://cxf.apache.org/core"
       xmlns:p="http://cxf.apache.org/policy"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <p:engine enabled="false" ignoreUnknownAssertions="true"/>
</beans>
Once this is done I tried searching way to disable the client side policy assertion as I was using the full wsdl with policy assertions. 

I wanted to control it at per http conduit level however, I didn't find anything clearly in docs or anywhere so I resorted to the last option of disabling it for the whole default bus for all the services/api's for now. 

 For disabling client side I had configure cxf.xml with following :
<!-- This is a Configuration File For Configuring Client Properties -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:p="http://cxf.apache.org/policy"
	    xmlns:cxf="http://cxf.apache.org/core"
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration
           http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
 
 <cxf:bus>
<cxf:features>
<p:policies enabled="false" />
</cxf:features>
</cxf:bus>

 <!--Following configuration states that client will wait for response for 1 hour-->
  <http-conf:conduit
           name=".*">
      <http-conf:client ReceiveTimeout="3600000" />
  </http-conf:conduit>
</beans>
This solved my immediate issue of consuming the API but I still need to understand and find a way to do it selectively as my app may have multiple clients in same JVM consuming multiple services and underneath using same CXF bus. Also, currently I don't have the option of having separate bus for each client/invocation.