Thursday, June 25, 2015

Improving Code Maintainability with Sonar and Jenkins

Problem Statement


Application code growing at an uncontrollable pace, few experienced guys in the team, challenging deadlines. All these made a heady nigtmarish mix for our application from maintenance standpoint.

Issue:
I was tired of the fact that people didn't seem to realize the importance of writing comments. Files after files, methods after methods were being created with no explanation as why they were needed and what purpose they solved.

Solution: 
This time I decided to at least try and put a stop to this never ending nightmare. The solution in my eyes lied in automating code reviews instead of just manually relying on it (which was exhausting and boring). We were already using Jenkins for building our code. I (with the help of a very talented colleague), added SonarQube feature to it. 
Then I tweaked SonarQube quality rules and made comment density a critical component. Initially I have set comment density at 5%. What that means is for every 100 lines of code atleast 5 lines of comments have to be there. If this criteria is not fulfilled for any of the checked in files on a given day, the build for that day will break, requiring urgent attention from team members.
The beauty of this feature is that even if a single line has been modified in a file (say as part of a defect fix), the person checking in the file would be forced to bring the entire file's comment density at par, thereby improving application readability and maintainability.

Below screenshot explains how to configure comment density in SonarQube.

Go to Dashboards>Quality Profiles> (Your quality profile)
Search for relevant rule by entering 'comment' in Search Box. Activate 'Insufficient comment density' rule and set its Severity.
 


Friday, June 5, 2015

Implement Throttling using Apache Camel

Problem Statement


Our application was getting huge surge of orders in small duration and at certain periods of the day only. To quanity further we were getting around 5000-6000 orders in a span of 30-45 mins, around 3 times in a day. Remaining time order volume was 100-300  orders in an hour. To tackle this load, number of app servers were increased from 4 to 8.

Issue
However the concern here was that this costly infrastructure was idle for most part of the day. Going by above stats, the servers were idle (usage much below capacity) for approx 70-80% of the time.

Solution
To optimize this we were asked to explore the option of Throttling.

Throttling: In software terms throttling is a  process responsible for regulating the rate at which application is processing.

Behaviour of application order processing before implementing throttling: Our application works by exposing a REST webservice. Client systems send order xml to this WS and its put on a JMS queue for processing.

Apache Camel Throttling PoC
I began by segregating above behaviour into two different components/routes.
One camel route listened to REST WS and put requests in a folder (say inbox). Another camel route listened to requests coming into this folder and put in on JMS queue but only after being throttled by Camel Throttling. Camel provides an option to define number of requests that need to be picked in a given time interval thereby making sure that even if order volumes surge, only pre defined amount of requests make it to processing stage. Rest stay in file system waiting to be picked up.

Sample code below:
<camel:route>
  <!-- Reading from REST url -->
  <camel:from uri="<REST WS url>" />
  <to
     uri="file:data/inbox?fileName=${header.OrderNumber}-${header.OrderVersion}.xml"
     pattern="InOut" />
</camel:route>
<camel:route>
  <!-- Route to put message from folder to main queue -->
  <camel:from uri="file:data/inbox" />
  <!--  Using camel provided throttling. Defined no of requests that can be processed in given time period -->
  <throttle timePeriodMillis="60000">       
   <constant>1</constant>
   <camel:log
    message="Sucessfully processing service order ${headers.OrderNumber}-${headers.OrderVersion}.xml" />
   <camel:to uri="file:data/outbox" />
  </throttle>
</camel:route>