Saturday, November 11, 2017

Apache CXF - Camel tips on WSDL Validation

I wanted to perform WSDL validation against incoming SOAP Payload.

Here's what I did:

1) In applicationContext.xml,

<cxf:cxfEndpoint id="MyEndPoint" address="http://locahost:test/" serviceClass="com.test.Test" wsdlURL="test.wsdl"  >
       
<cxf:properties>
            <entry key="schema-validation-enabled" value="true"/>
        </cxf:properties>

</cxf:cxfEndpoint>
2) In camel-context.xml, 
<camel:route id="myService">
   <camel:from uri="MyEndPoint?dataFormat=
POJO"/>
...
</camel:route>
**It is compulsory to use POJO so that it will trigger JAXB validation. Otherwise you won't see any effect. Read this RedHat's document for further study. 

Apache CXF - Camel tips on Working On HTTP Response Header

Apache Camel provides so many features. It is like a blackbox.

I wanted to change the default value of the Http Response Header, for example to set no-cache to the Cache-Control. Here's what I did:

1) Create SoapInterceptor class by extending org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor
public class SoapInterceptor extends AbstractSoapInterceptor {
2) In the constructor, set the below line: 
        super(Phase.PRE_PROTOCOL);
        getAfter().add(SAAJInInterceptor.class.getName());
**For Phase, please read this documentation from RedHat . If you wanna become an expert in terms of this, you need to test it out one by one to master its behavior. I think it is wise to include that kind of effort to your project timeline. 

3) Implement the handleMessage(SoapMessage message) method. 
3) Inside this handleMessage, I obtain the HttpServletResponse from the below line: 
HttpServletResponse httpResponse = (HttpServletResponse) message.get(AbstractHTTPDestination.HTTP_RESPONSE);
4) Now I can set the following: 
httpResponse.setHeader("Cache-Control", "no-cache, no-store");
5) Next, in applicationContext.xml,
<cxf:cxfEndpoint id="MyEndPoint" address="http://localhost/test" serviceClass="com.test.Test" >
<cxf:inInterceptors>
            <bean id="inInterceptor1" class="com.test.interceptor.SoapInterceptor" />
        </cxf:inInterceptors>

</cxf:cxfEndpoint>

Friday, April 14, 2017

One URL, Different Certificates

Yesterday I encountered one very weird issue where the web service that my application consumes, actually generates entirely different certificates if you access from browser!

That's a new finding for me. 

What I do normally is to download the SSL certificate from internet browser such as IE. After that I will add the SSL certificate that I downloaded to my application's truststore. This way has worked many and many times before and has never gone wrong. 

However, unfortunately this time the above method did not work anymore. I then troubleshooted the application by enabling the Java SSL Debug mode by adding the JVM parameter "-Djavax.net.debug=ssl" so that my application would print out the SSL debug information to the STDOUT. From there I spotted this line "certificate_unknown", then I further confirmed the CN details of the SSL certificate received by my application from the Web Service Provider is different that the one that I've added to my application's truststore. 

Next I chose to retrieve the SSL certificate by using openssl. I installed OpenSSL for Windows , then ran the following command "openssl s_client -connect host:port" to fetch the SSL certificate details. I saved the details as a CER file, then added that CER to my truststore and hooray my SSL handshake issue is gone!