Monday, September 23, 2013

Don't forget to use NIO if you are doing Async stuff with servlet 3.0 and using Tomcat 7 or below

If you are using Servlet 3.0 API to do some async stuff, do not forget to switch to NIO Connector by setting protocol attribute of the connector element in server.xml and using an executor. There are two important reasons for this: Thread pooling and timeout behavior of AsyncListener.

About Threads

There are 10 threads in my ExecutorService to handle requests in my AsyncContext pool. Here is a sample; let's assume that we push awesome data to clients in a comet fashion such:

If you leave Tomcat 7's default configuration; you will have n+10 threads. "n" is the number of requests. This is due to nature of blocking connectors. This might be useful for some applications (where for example thread local variables are highly used etc.). However; due to nature of the asynchronous job we are doing (we are pushing data to client when an event occurs) what we like to achieve is to satisfy all the clients with less threads; since most of the time threads are doing nothing but waiting.

Change your connector to NIO and use a thread pool for the NIO connector as seen from a server.xml fragment below:/p>

Connect with jprofiler; send 500 threads with jmeter; you will see only ten threads at the front; delivering those requests to 10 worker threads we defined above. To make it really look like a node.js; set maxThreads="1" minSpareThreads="1" of executor element. There were no changes in performance in my case due to fact that I wait for a second in my loop which schedules pushes to clients; so each client is pushed once a second approximately. In real life; an event will cause this push.

I really like this architecture rather then node.js due to fact that I know exactly the thread counts and I can manage them all. And please post me why node.js is better? I just can not understand. You have more libraries in java, you can integrate with many other systems easily; you can write in java,ruby,js,groovy,scala etc..

About Timeout

If your are setting timeout on AsyncContext such:

And then add an AsyncListener to that AsyncContext; OnTimeout of AsyncListener is called depending on which connector of Tomcat you are using.

If you are using Http11Protocol (BIO): callback is called exactly the time passed from the first request. If you give a high timeout and user closes his browser; still timeout is not called and you have to push data since you are not aware of it.

If you are using org.apache.coyote.http11.Http11NioProtocol (NIO); callback is called exactly the time you set after the connection is closed (for example if the browser is closed).

Thursday, September 12, 2013

Spring Integration; WS-Outbound to Exchange Server with NTLM

Although NTLM is insecure and being deprecated; I was required to transform basic http authentication to NTLM.

First download and place jcifs.jar to your classpath: (If you are using maven; upload this jar to your repo and use it in your pom as described here.)

Use the above message sender as displayed below in your ws outbound gateway.

Thursday, September 5, 2013

Datapower: Extract an URL from XML, fetching content and binary transformation

I would like to share a simple configuration I have done in order to extract an URL from given XML, fetching it and encoding the content while returning it in soap response. It might be valuable for those who are looking for selecting xml elements in xsl regardless their namespace and how to transform binary content.

First we should extract ip, port, path and query arguments and construct a full URL. No need to say that this is the worst representation for an URL; but this is what asked from us.

A sample xml is: The URL extractor XSD is (AtmesUrlExtractor.xsl in policy flow):

After extracting the URL and assigning the result to a variable atmes_fetch_url; we use fetcher component to fetch the content (in this point we reference to variable with var://context/atmes_fetch_url):

This fetcher puts content is into "PIPE". Then our binary transformer is activated:

The important thing above is call to pkcs7-convert-input.ffd. It puts all the content in a xml structure so that we can proceed with xslt although it is not an xml actually. It is very easy to understand how it works; it is a standard file in datapower. It puts all the content under object/message tag. The import thing is that you must choose it as a binary in component details screen as seen below (even if it is not a binary; a text; anything which is not xml.)