Thursday, December 25, 2008

SSL security at different levels

Sometimes a server might have a requirement to receive requests over a secure line. Installing SSL certificates on your server will help you achieve the same. Where you install this certificate on the other hand might affect how your application behaves. Java for example allows you to detect if a line is secure by exposing the isSecure() method in the HTTPServletRequest interface.

So, we had a requirement where users had to submit documents over a secure line. In order to ensure requests were secure, a piece of code checked the same using the isSecure() method. A web server might well have the capability to block insecure requests to a given URL. But the code was written anyway as a backup to check for the line's security.

The code worked well in the DEV and Local environements where the SSL certificate was installed on the application server. When the code went into the QA environment - KABOOM. Every request was declared insecure and thrown out. A little investigation revealed that the certificate in QA was installed on an IIS web server, behind which was our application server. The same configuration was available in the live environment. Testing in the Local and DEV environments was performed with the certificate installed on the application server. A web server was available only in QA, which was one of the reasons this problem slipped past us. Since the line between the web server and the app server is not secure (but the line between the user and the web server is secure ), the isSecure() method returned false all the time.

Secure lines in QA:

Configuration in DEV and Local:

It pays to know your environment well before you design / write code. Code usually fails when we fail to take into account details that would not normally be considered while testing. Configuration settings, Application server patches, batch jobs, scheduled tasks etc are to name a few.

Sunday, May 18, 2008

A better way to iterate java maps

Imagine you have a map like so

Map <Integer,String> map = new HashMap<Integer, String>();
map.put(0, "Value1");map.put(1, "Value2");

I often see code written in this fashion to Iterate over the map

Not so good code:

You can instead use the following code to iterate through each entry. A map is nothing but a series of Map.Entry objects. It is better to get a reference to Map.Entry and then iterate instead of getting all the keys and making the Map object do the work of fetching the value each time

Good code:

Sunday, April 13, 2008

Writing PDF charts with iText in less than 2 minutes

If you didnt already know, iText is an API through which you can write dynamic PDF content from a java application. iText is strong contender for being a solution that can be applied across different environments. Given the increase in the number of applications using PDF these days, an API like iText makes life a lot simpler for developers.

iText is also integrated with other libraries out there like the JFreeChart API. This means that you can create a JFreeChart object and pass it to an iText method and expect PDF content to be returned as a result. That is pretty neat and the solution can be applied over a number of places. Given below is a brief overview of charts that can be created and converted to PDF format.

To begin with lets create some JFreeChart objects that resemble a piechart and a barchart given some random data. The code snippet below would do the trick to accomplish this. Its not rocket science really. The code is self explanatory. You add a couple of name value pairs and mention how much of the chart area each value is allowed to occupy. Once the JFreeChart objects are constructed we can go ahead and convert the objects to PDF format.

Get a bar chart:

Get a pie chart:

To convert these objects to PDF, first declare a Document from the iText API within a defined Rectangle. Use a PdfWriter object to write the contents of the PDF. The iText API is capable of creating a java AWT Graphics2D object based on a given PdfTemplate. Use the JFreeChart API to draw on the Graphics2D object and that is pretty much it ! Here is some code

Converting JFreeChart objects to PDF:

Run the program by calling the appropriate methods:


Bar PDF:

Pie PDF:

Besides you can integrate this solution with java SWING if you wanted to since it supports AWT objects. You could also write to a browser by getting hold of a response output stream instead of a file and thereby allowing your users to experience rich dynamic PDF content on the fly. iText is capable of much more, like

  • Working with tables
  • Image support
  • Fonts
  • Indenting and nesting
  • Interactive forms with PDF
  • RTF Documents
  • Digitally signing a PDF

There is much more to the API than the list mentioned above. If you are to work with this API I would recommend that you buy the iText in Action book from Manning. The example in this post is based on examples from the book and it really does deliver details of the API in a short and sweet format.

iText in Action:

Monday, March 24, 2008

Converting integers to String in Sybase

I had to manually insert some data into a sybase DB recently to correct a recurring faulty programming logic. An application was attempting to insert 4 rows into the database. Of these rows, 1 row of data was already available in the database, so a primary key violation was raised by the application and the rest of the data never made it into the sybase DB. Since this was a recurring problem I simply took the previous SQLs written by some one else to fix this and inserted 3 records into the DB.

Here is what one of the SQLs did



insert into table values (str(@variable),'value',1,12.6)



The @variable here was a primary key. This value is obtained dynamically each time as an integer and then converted to a string. For the sake of discussion lets assume it was 11576. The SQL worked pretty well and everything seemed to be going fine until I executed the following query on the sybase DB

select * from table where primary_key = '11576'

To my shock the row from the table was never returned. I did not understand why, because this same SQL was executed previously to fix the problem. I modified the SQL to the following

select * from table where some_other_value = 'value' and something = 1

Now the row was returned and I could see quite clearly that the primary_key was still 11576. Since it was a string i began to suspect that spaces might be a problem. Another modification

select * from table where primary_key like '%11576'

This time the row was returned again. After going through the documentation for the str function, i figured it out. SELECT STR( 12345 ) would return '(5 spaces)12345'. When some one wrote this SQL they had assumed that str(number) would return the exact string representation of that number. Instead I used convert ( varchar(5), @variable ) and things worked as expected. You could also use SELECT STR( 1234.56, 6, 1 ) to return 1234.6. Here the length and the decimal places are mentioned.

Lessons learnt here
  • Never assume that a previous fix is flawless
  • Consult the documentation when in doubt