Monday, January 17, 2011

Issue on starting RabbitMQ 2.2.0 After Installation via MacPorts

I used MacPorts to install RabbitMq 2.2.0 on  my Mc OS X (Snow Leopard) laptop. After installing I tried running the command sudo rabbitmq-server and I get an error saying there's already a rabbitmq process running. The startupitem.log from /opt/local/var/log/rabbitmq indicated the broker started successfully, using the domain localhost. I was expecting it to use the domain mycomputername since that is what i have configured in my /etc/hosts file. I cannot connect to the node rabbit@mycomputername when I try to run the command rabbitmqctl. Somehow rabbitmq-server is using localhost domain while rabbitmqctl is using mycomputername domain.

Did more digging and found out that the daemon generated by MacPorts after it installed RabbitMQ was getting spawned when my computer starts up. But the problem is it's using localhost as the domain instead of mycomputername. When I try to kill that spawned process, rabbitmq automatically re-starts and now using the node rabbit@mycomputername. So I can now use rabbitmqctl command and query the rabbitmq server. To permanently fix the issue, I have to remove the plist file org.macports.rabbitmq-server.plit which defines the start/stop behavior of rabbitmq-server which is registered as a global daemon process that will automatically kick-off when my computer boots up.

After removing the plist file, and manually starts rabbitmq by typing sudo rabbitmq-server, I no longer see any errors. I wasn't sure why MacPorts generated that plist file that always uses localhost as it's domain instead of mycomputername when it starts rabbitmq-server initially.

If your erl_crash.dump file contains the string below you might have the same problem. Either check to see if you have configured your /etc/hosts file properly or that you are having the exact same problem I just came across with.


no_hosts_file
'Warning: No HOSTSFILE specified!'
address
'Warning: No NAMESERVER or RESOLVFILE specified!'

Glad I can start playing around with RabbitMQ!

Tuesday, November 30, 2010

Working as a Consultant

Wearing many hats at work is what interest interest me with my job. Being a Consultant definitely provides that. Meeting clients, talking about their needs, identifying technology platform, designing the system and managing a development team are just about the things I've enjoyed doing.


Developing a system in-house for a client makes the development and management effort very interesting but I find there are two most critical things that needs to happen before a single code is written as shown below.
  • Validating verbal and written client's development platform
  • Knowing how your client's think, how your client's work, and what makes them happy.
Asking a client's system environment  is not enough to produce a product's platform development. One should consider validating the client's environment by developing a dummy framework built according the to their system specification. Try dropping that framework onto their server and start running some dummy test cases. This will validate the version of the programming language being used, modules installed, security restrictions and some unknown and known incompatibilities. Some client's environment are tightly secured even down to the smallest feature of an application and sometimes this is what makes developing/deploying an application difficult. Validating an environment by writing a sample framework is the surest way to know exactly the platform one should be developing on.

Now, another interesting thing to note is that when you understand who your clients are and how they think, it makes it a lot easier to work with them and  one can pretty much predict how the application should be designed and created. Carefully listen to what they need and how it should be incorporated to the application. The culture of the company reflects on their personality and this is what drives what they produce and use. A consultant should be able to identify and classify business functions that are most critical, important and least important. 

Internationalizing Java Web Applications Part I

Internationalizing an application can become a daunting task. Specially if the application already existed for quite some time. What more if the business decides to support a huge number of languages? There are several things to consider to ensure that the application displays the correct translation according to its locale. This is just the minimum list but there might be some other stuff to consider. Let's start with the list below.

The Setup:
1. Windows Server
2. Windows XP Client Machine
3. Java Web Application
4. SQL Server 2005
5. Firefox/IE

1. Browser Support
2. OS and Microsoft Office Language Settings
4. Database Internationalization Support
6. i18n Bundle - Property Files and Data
7. Font Support (Highlight If Text is embedded in an image)
8. UTF-8 Encoding
9. JSON element/data Encoding/Decoding
10. The Locale class


Browser Support
This is the easiest to figure out. Lots of browsers out there supports tons of languages. It's just a matter of choice.


OS and MS Office Language Settings
1. OS Server
The operating system should have been installed with the languages the users are interested in. At least the english (en_US) language and make it the default language. You can check what the OS supports by checking the Regional and Language Options if your server is Windows based. There you can see Standards and Formats of the currency, number and time from the Regional Options tab. While the Languages tab shows the option to choose what Text Services and Input Languages to use and allows one to install East Asian Language Support and this is really important specially if we are working with Chinese, Japanese or Korean language. 


Now for an Application Testing Environment that supports many different languages, the server can have the English [United States] setting from Regional Options and leave the other properties unchanged. If Japanese, Chinese or Korean or any East Asian Language is needed for the application, then the East Asian Language Support must be installed.


To test if the language settings are correct, drop a text file that contains data with the language of interest to the server. Open the file. If the data is in Chinese, then the text characters should show up as Chinese characters. Otherwise, the language settings aren't right.


2. OS Client
On the client side, there must also be Language settings that needs to be done. The OS should also have come installed with other languages. But the East Asian Language is by default not installed. This must be installed if Japanese, Chinese or Korean needs to be supported.


3. Microsoft Office
Apparently, Microsoft Office needs to be tweaked to properly display East Asian characters. No tweaking is necessary for other languages. Just go to Microsoft Office Tools and click on Microsoft Office Language Settings. There you can enable other languages for proper viewing of data.


Database Internationalization Support
All major database products supports internationalization. It should be able to support Unicode characters or the literal character of that language (by using the prefix 'N' when inserting data into the database).


I18N Bundle
All internationalized app have i18n bundle which is used for displaying the appropriate label, description or error message to the application. This bundle is basically a jar file containing all the supported languages or locales. The files in that jar are properties file of the form I18N_locale.properties (i.e. I18N_en_US.properties for English US). So each properties file is composed of a key/value pair. If this is done right, then you avoid a lot of translation issues. The number of keys from the default locale, say en_US should match the number of keys in the other locales. The value for each key must be translated for its target locale. 

Thursday, March 4, 2010

Atlanta ITARC 2010

One of the presentations that really got me the most was from Bill Cason's Enterprise Architecture 2.0. He works for Troux Company. I thought he was phenomenal in terms of unveiling key ideas in making an IT organization successful in meeting business needs.

He didn't talk about technologies and trends but mainly focused on how should an enterprise architect treat his relationship with the business people and how he should realize things that matters most to the business. Here are some concepts he shared worth noting.

10 Critical Success Factors For Enterprise Architecture

  1. Seek expert help to setup an Enterprise Architecture practice
  2. Have Executive Sponsorship
  3. Clear Roll-out Plan
  4. Strong Internal Program Leadership
  5. Focus on Enterprise Architecture Adoption Process
  6. Laser-focus on business value
  7. Leverage the wider data team
  8. Automate the data collection process
  9. Market your success internally
  10. Flexible Enterprise Architecture Technology to enable successful Enterprise Architecture

10 Lessons Learned
  1. Focus on what is important to the business NOW
  2. Align with allies, don't waste time with disbelievers
  3. Seek funded, complex initiatives
  4. Careful when "moving cheese". Consider politics in play.
  5. Create sustainable process
  6. Publicize your results
  7. Recognize stakeholder needs
  8. Avoid being the bottleneck. Federate and participate.
  9. Leverage established best practices
  10. Implement incrementally
Also, IT must show cost transparency and must know what compliance the business supports.

Tuesday, February 9, 2010

Executing MySQL Scripts in Batch Mode

I wrote a script that would accept a file path and traverse through the directory tree to search for files with extension *.sql and load those sql scripts into MySQL and run them.
My *.sql files are basically scripts that builds database tables. 


Here's what I've done;

################################################################################
#!/bin/sh

# Reads the specified directory and traverses for the sql script files.
# The first argument($1) is the target directory to be searched.

#Read the files in the directory and generate the table creation statements separating them using the semi-colon delimiter
# If there are sub-directories, they will be traversed and all files ending in '.sql' will be processed
source_queries=""
source_command="source "
echo "argument passed $1"

for file in $(find $1 -type f -iname '*.sql'); do
source_queries="${source_queries}${source_command}${file};"
done

# Uncomment to printout generated queries/statements for debugging purposes
# echo "printing statements generated ${source_queries}"

# Connect to the database using the 'stratus' database and execute the query statements generated
# This can be run on the background as well

echo "Executing database tables creation scipt......."
mysql -u myuser --password=mypassword --database=mydatabase -e "${source_queries}"
echo "script completed...."
#################################################################################



Say if there's 1 script file with filename create_person_table.sql under the target directory /opt/db_scripts the resulting mysql command would look like this


mysql -u myuser --password=mypassword --database=mydatabase -e "source /opt/db_scripts/create_person_table.sql"


If there are multiple sql files the clause on the '-e' option would look like this


mysql -u myuser --password=mypassword --database=mydatabase -e "source /opt/db_scripts/create_person_table.sql;source /opt/db_scripts/create_employee_table.sql"







Saturday, February 6, 2010

JUnit

The setup() and tearDown() methods of the TestCase class apparently behaves differently from what some people would have thought. If these methods are used in a test class, one would think that it would be only called once for the lifetime of the test class. But it is not the case.

To illustrate this further, lets consider the sample code below. It's main purpose is to show how the methods above behaves when the test case is run.

Say we have this test class:

1.public class TestPerson extends TestCase{
2.       private Person person;
3.
4.       protected void setup(){//create Greg
5.           person = new Person("Greg");
6.       }
7.
8.       protected void tearDown(){
9.           person = null;
10.      }
11.
12.       public void testCreateChild(){
13.          person.createChild("Nimfa");
14.       }
15.
16       public void testMarrySomebody(){
17.           person.getMarriedTo("Laila");
18.       }
19.}

When this test case is run, here's what's going to happen:

1. At line 2, the person variable is declared and initialized
2. At line 4, setup() method is called
3. At line 12,  testCreateChild() method is called (assuming this is the first method called)
4. At line 8,  tearDown() method is called
5. At line 2, the person variable is declared and initialized again
6. At line 4, setup() method is called is called again
7. At line 16,  testMarrySomebody() is called
8. At line 8,  tearDown() method is called

After code execution, Greg will loose a child names Nimfa then get married to Laila instead of having both the child and getting married. Sad story....

Here's the explanation. In a nutshell, the number of test methods we have, in this case two(testCreateChild() and testMarrySomebody()), is directly proportional to the calls of the setup() and tearDown() methods and to the declaration and initialization of the member attributes. The variable person will be instantiated again with a new Person object but with the same value which is 'Greg' for each method loosing the previous state of the child created. Greg will always end up getting married and not having a child.

If the intention on line 5 is to create an object which has a state consistent across all test methods, then it is a problem, since JUnit will basically create a new object per test methods. Object state maybe different from each test methods. The best approach would be to not use the setup() but instead initialize the object in the test method itself. So the object(s) initialized at the setup() method is never reused to the rest of the test methods. The tearDown() method is not necessary since it's just destroying the created object unless, a specific resource(i.e. database connection, etc.) needs to be released and should be called here.

Tuesday, February 2, 2010

Ten Commandments of Egoless Programming

A friend from work forwarded this information to me, which hed extracted from a TechRepublic article and I thought it was pretty interesting. I'm the Apache Software Foundation Group follows this very much, as it reflects how good their software products are and its free!!!

Here are the 10 Commandments of Egoless Programming, my friend willingly shared.

1. Understand and accept that you will make mistakes.
2. You are not your code.
3. No matter how much "karate" you know, someone else will always know more.
4. Don't rewrite code without consultation.
5. Treat people who know less than you with respect, deference, and patience.
6. The only constant in the world is change.
7. The only true authority stems from knowledge, not from position.
8. Fight for what you believe, but gracefully accept defeat.
9. Don't be "the guy in the room."
10. Critique code instead of people-be kind to the coder, not to the code.

Friday, January 8, 2010

Installing Solaris 10 Software Companion CD from ISO Image

To install the software companion from an iso image on a solaris machine follow this steps:

1. Type the command lofiadm -a /export/temp/software.iso. This command creates a block device from a file which can be mounted. The block device will look something like this /dev/lofi/1.

2. Mount the block device by typing this command mount -F hsfs -o ro /dev/lofi/1 /mnt. We are mounting a file system of type hsfs(High Sierra File System) which is basically a representation of our iso image (compact disc). We can also use the cdfs(Compact Disc File System) if the file is being mounted from a cdrom. The ro option basically means its a read-only.

3. You can install one package at a time, but for the purpose of this demo, I'm gonna install all of the packages. Next step is to create an admin file say on this path /var/tmp/admin. The admin file should be created by root user. It contains the following:

mail=
conflict=nocheck
setuid=nocheck
action=nocheck
partial=nocheck
instance=overwrite
idepend=nocheck
rdepend=nocheck
space=check

Now this will install the packages without having the user interact with the package installation.


4. Change directory to the location of the software companion packages relevant to your architecture. In my case I'll be installing it on a Solaris 10 OS. After changing to that directory it should look something like this /mnt/Solaris_Software_Companion/Solaris_sparc/Packages.

5. As a root, execute this command pkgadd -a /var/tmp/admin -d /mnt/Solaris_Software_Companion/Solaris_sparc/Packages. The -a option overrides the default admin file with the one we just created. 

6. Once it executes, it will display all the available packages to be installed and will asks you to install a package or all of the packages. Choose 'all'. Installation will proceed to run.



Friday, January 1, 2010

Installing CouchDB Version 0.10.1 On Fedora 4

I've heard about the hype on CouchDB from this link NoSQL and the design behind it is pretty interesting. It's a different kind of database that doesn't use schemas at all. Built on Erlang which is a well known language solid enough to handle a grand scale of processes without sacrificing performance. Its data structure is a B-tree and uses MapReduce to traverse it at an incredible speed. CouchDB is document based and provides the option of
working online and offline. With its interesting characteristics, I decided to install it on my Fedora machine.

Here are the dependencies I've installed (assuming everything was a downloaded source):
    1. curl-7.19
    2. SpiderMonkey - js-1.7.0
    3. ICU - icu4c-4_2_1
    4. Erlang OTP - otp_src_R13B03
    5. autoconf-2.13

Somebody had provided a script to properly and easily wire SpiderMonkey with CouchDB as can be seen from http://74.125.47.132/search?q=cache:http://dt.in.th/2008-03-03.spidermonkey-linux.html. This is our script:


#!/bin/bash
if test "$USER" = root; then
    wget http://ftp.mozilla.org/pub/mozilla.org/js/js-1.7.0.tar.gz -O- | tar xvz
    cd js/src
    make -f Makefile.ref
    mkdir -p /usr/include/smjs/ -v
    cp *.{h,tbl} /usr/include/smjs/ -v
    cd Linux_All_DBG.OBJ
    cp *.h /usr/include/smjs/ -v
    mkdir -p /usr/local/{bin,lib}/ -v
    cp js /usr/local/bin/ -v
    cp libjs.so /usr/local/lib/ -v
else
    echo "You must be root. Try sudo $0"
fi



To ensure that CouchDB will compile properly, use the options --with-js-lib and --with-js-include when installing it. Type the command couchdb to run it. Then try to run this command curl http://127.0.0.1:5984/. You should see something like this {"couchdb":"Welcome","version":"0.10.1"} as the response. This means that the database was successfully installed.

Futon is a great web interface to the database. Be sure to run all tests from Futon. If the URL used to access Futon is say http://localhost:5984/_utils, there are 3 tests that will fail - oauth, replication and security_validation. This is a known issue for some common network configurations. My setup is basically a Windows XP accessing thru Futton the CouchDB server instance  which is installed on a Fedora machine. Both machines are connected via a router without any DNS configurations. Whatever the network configuration is, this URL will always work and all tests passes - http://127.0.0.1:5984/_utils.

I prefer a different ip address used to access Futon so I went ahead and updated two configuration files which are default.ini and local.ini. The settings from local.ini will override the default.ini. Depending on your installation of CouchDB, these files can be found at /usr/local/etc/couchdb directory. Change the binding address to suit your needs.

Tuesday, December 22, 2009

Checksum App for Windows is a Worm!

Do not download the Checksum App from this site http://corz.org/windows/software/checksum/ . Once downloaded and run, a worm is loaded! Please see the image below. I'm glad I had my Lavasoft Ad-Aware running. Somehow my McAfee didn't detect it.




Saturday, November 14, 2009

Internationalizing Numbers and Dates in Java

Locale
It's easy to be tempted to find a tool that can do a specific job. Consider formatting Dates and Numbers for different countries. If you do find a tool, great, but that's just making your application dependent on another tool and redundant since Java already provides you an API that does the job. There's a ton of language support that Java provides. If Klingon would become a language in the future, I'm sure Java will support it, hopefully here on earth.

A Locale in Java is a representation of the Language and the Country. It's also a class. Their's two properties of it that is a must - language id and country code each of which consists of 2 characters. Say if you have the German language, the locale is "de". If the language is still German but of the country Austria then the locale is "de_at". Locale for United States would be "en_US". There's a lot of websites that explains the different locales in different countries so I'm gonna leave it out.

When instantiating a Locale take its important to note what arguments are being passed to its constructor. I've come across a bug in one of the applications I've worked at where a line of code was passing a language id of this form languageId_countryCode where in fact it should only be languageId. If you need to pass both to the constructor, separate those two values out. See example below.

Locale germanLanguageId = new Locale("de_at"); // wrong assignment of locale value.
Locale germanLanguageId = new Locale("de"); // correcet assignment.

If both the language id and country code is needed then it should look like this.

Locale germanLanguageIdAndCountryCode = new Locale("de", "at");

Localized Or Internationalized Date
This is pretty straight forward. Just use the DateFormat class and pass in the right locale to get the right date display as shown below. When you actually want to get an instance of that class, use the factory method getDateInstance(int style, Locale locale).

Date date = new Date(); // Now the date can be of any type as long as its an object.
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
String internationalizedDateString = dateFormat.format(date);

Now depending on your current Locale, let's say we are using the german language id de, their date would actually be in this format. This is due to the fact that we chose the format type SHORT.

dd.mm.yyyy // so for todays date in german it would be 14.11.2009, thank goodness I decided not to write
                   // this yesterday!

Now for locale en_US it would be 11/14/2009. Of course the code will take care of doing the formatting for whatever locale the application is supporting.

Localized or Internationalized Number
First thing to do is to always define the pattern of the number that we would like to show in different locales. When I say pattern, its how many zeros do we want to show and if we don't want to show anything is the value of the number is equal to zero, etc. The DecimalFormat class has a method applyPattern(String pattern) where we can plugin the pattern we want. We can get an instance of this class by using the factory method of NumberFormat and cast it to DecimalFormat as shown below.

float aNumber = 1,500.98;
DecimalFormat decimalFormat = (DecimalFormat)NumberFormat.getInstance(locale); //factory method
decimalFormat.applyPattern("#,##0.00"); //our cool pattern
String internationalizedAndFormattedNumber = decimalFormat.format(aNumber );

Now the pattern #,##0.00 means that the grouping of the number is in thousand. The hash sign is any digit, where if its zero it won't display that number. The zero in the pattern is a digit, where if its zero, it would display as 0. We are also restricting the number of digits after the decimal to two digits. Say if we have a number 1,450.50 in english locale (en_US), upon formatting this to german (de) it should show up as
1.450,50. The comma becomes as period and the period becomes a comma. Of course, if the number we are trying to format is in millions, then our pattern should look something like this #,###,##0.00.

If the pattern is missing, some numbers get displayed in some other locales and some would display just fine. If our number is 0 to be formatted in german it might appear like this 0.0E3 which just confuses our business people looking at our localized spreadsheet. A pattern must be supplied always to display the right number in the right format. If a number in our localized csv file displays as 12.61 and then opened in excel, that number will be translated into a date equal to December 1967. This is the side effect of not supplying a pattern.

One last tip, if an application is processing data and converting it into CSV for excel viewing, remember to replace all carriage line feeds or new lines embedded in a String value with an empty String (" "). Say we have the String "The value\n is supposed to be\n entered here". This value should be in one row on a cell right? But with the new line character \n excel will actually break those strings into 3 rows. It would be

                Cell A
Row 1     The value
Row 2     is supposed to be
Row 3     entered here

Have fun with I18N !


Thursday, October 15, 2009

Working with Deleting/Updating a Set In Hibernate

If a hibernate mapping object contains contains a Set of objects, it's usually configured with the attribute 'set'. If you want hibernate to take care of updating/deleting those objects in the set from the database table, the set attribute cascade must have the value "all-delete-orphan" and properly handled in the code that tries to update it.

Say our parent object is Car and child objects are of type Part. Our set mapping would be of the form below








In order to make the changes to the set elements which are of Part type, the order of the update statements must be of this sequence.

Car car = manufacturer.getCar();

//we want to reduce the number of parts say from 10 to 8.
//If the two parts have the ids 9 and 10, then let's remove it
Set parts = car.getParts()

//iterate through the set and grab the objects with ids 9 and 10

Part part9 = (Part)iter.next();//assuming this is the 9th object in the set
Part part10 = (Part)iter.next();//assuming this is the 10th object in the set

parts.remove(part9);
parts.remove(part10);

//persist to database to update the records

saveOrUpdate(car); //this will merge the differences. the database record will //now have 8 rows instead of 10 for the parts. Also, you can use the merge(car) //method and it will work the same way.

//if you want to delete all parts since its no longer produced, just do this
parts.clear();
saveOrUpdate(car); //then there will be zero entries for the parts in the database table

//When it comes to adding a new part, just add the new part object and persist.
Part part11 = new Part();
//...fill properties
parts.add(part11);
saveOrUpdate(car);

Wednesday, September 30, 2009

JFreeChart LegendTitle Font Change

I've been trying to search the whole day yesterday on how to change the Font for a chart's legend title. JFreeChart doesn't have any good free reference documentation about this use case but I was finally able to figure it out by playing with LegendTitle's methods. The code below works for changing the Font of the current LegendTitle object.

LegendTitle legendTitle = chart.getLegend();
legendTitle.setItemFont(font);
legendTitle.setNotify(true);

The setNotify() method somehow alerts the different objects dependent on the LegentTitle and update it's state. If that is not called, nothing happens. If that method is set to true that means, the current change on the chart, specifically the LegentTitle, call all dependent objects and notify of this change and properly act on it.

Monday, July 20, 2009

iPhone Mobile Camp Atlanta

Last Saturday, July 18th, I went to attend the Mobile Camp Atlanta in Marietta the whole morning. There were alot of presentations to choose from crossing iPhone, Android, Palm-Pre, Windows Mobile, Blackberry development. But I mainly focus my interest in the iPhone seminars. The iPhone Development presentations covered best practices user interface design, Parsing XML, Core Data, JSON, Facebook and Analytics, Push Notification. I've attended all of them except for the last one.

I am not an iPhone developer but I'm looking into getting converted before the end of the year. After the end of the presentations, I'm decided to add in my skills Objective C Language which apparently iPhone is using. I believe phones in the not so distant future will become a critical part of the IT Enterprise Infrastructure in terms of delivering important, well formatted content to the business user or customer. I'm sure iPhone will become a great tool to realize this need.

Here's what I've taken for each presentations.

iPhone App Design Best Practices
1. Be true to the device. Know the capabilities of the hardware and what the API can provide.
2. Read the Human Interface Guidelines provided by Apple.
3. Start designing your app after item 2 & 3 are done.
4. Use DataObjects metaphor.
5. Start button design to 324x80 pixels and load it to a temporary button album in iPhone just to see how it fits.
6. Use a third party tool like iView for viewing prototypes of the interface design. You can also use iPhone Stencil created by Design Commission.
7. Remember that 3G S has warmer color that its predecessors.
8. Perform Paper Prototyping to understand the flow of the application.
9. Native apps are more comfortable with users than browser based ones. Native in this context is Objective C.
10. Do not hardcode the screensize, iPhone itself might change the lcd screensize in the future plus if you are developing on iPod as well.
11. Let the app be customizable by users to make it their own. User experience is a need.
12. Pixel density of iPhone is much higher than what you have in a laptop or desktop. The prototype from the laptop/desktop will look different when viewed from iPhone.
13. As a rule of thumb, always design apps both for iPhone and iPod.

Parsing XML using NSXMLParser
The NSXMLParser is SAX based parser. It rides on top of Cocoa. This goes hand-in-hand with NSDictionary and NSArray. NSDictionary allows you to store key/value pair. Like a Map in Java. To manage multiple occurence of same key, which are basically the xml nodes that you are trying to get onto, turn it into an array. This is only true for one level node. For deep level nodes, give the parser a hint then build the array.

Introduction to Core Data
Core Data in iPhone sense means Persistent Objects. All apps have a delegate. iPhone uses managed object model and context. There are 3 main APIs suitable to perform manipulating persistent objects - NSString, NSArray and NSDictionary.

JSON in iPhone
Use the JSON documentation from iPhone Noob. The only thing to do to deserialize JSON objects are to turn them into Dictionaries and Arrays. By the way, the debugging in XCode looks really cool.

FaceBook Connect in iPhone
I'm not really intested in developing applications via FaceBook. But if you do, all you have to do is download t FaceBook Connect Dev and apply to obtain "API Key" and "API Secret".

Analytics for iPhone
This was mainly a discussion about a product called Flurry, which is a better version of iTunes analytics. This comes close to Google Analytics. The presenter just basically showed us on the web his product he created and it does have much more meaningful data than iTunes does.

Tuesday, May 26, 2009

Integrating Author It Compiled Documents with Strutsonlin

Integrating the end product of a content management tool with a web application is painful. Even if the web application is built on top of an MVC framework. Author It is a CMS tool that will let you build an html based documentation. The focus on this discussion is integrating an end product which is an online help documentation with Struts. 

The documentation will allow users to view the help page regarding the current page by clicking on the Help button from the menu bar of the application. The user can also search for any specific help pages she/he wants to view. 

The integration effort requires several files to be created/edited as listed below

1. onlinehelp-config.xml
2. onlinehelp.jsp
3. common.js
4. mainMenuBar.jsp
5. web.xml
6. OnlineHelpProcessor class

and several classes as shown below from the diagram


onlinehelp-config.xml
This file contains the mapping between struts/tiles and the online help html documentation page through its numeric code which is the prefix to the file name of the help page (i.e. 207.htm). There are two parent nodes in it - nonupdate and update. 

nonupdate node contains mapping for help pages that are "only" non-editable web pages while the update node maps help pages to editable web pages.

The element is the tiles definition name attribute. This configuration is read and cached when the application starts up. Think of the element as the help page file name appended with .htm.

onlinehelp.jsp
This is the original index.htm file generated by Author It tool, the entry point for all help documentation pages. There are three modifications to this file - import of the taglib struts-bean.tld, bean definition of the onlineHelpCode and the SRC attribute value of the frame element. 

The import of the bean taglib is needed to extract the SessionData bean which lives in the session and get the onlineHelpCode string value from it and plop it to the SRC element. It is important that this file is located where the jsp files are.

common.js
Of course we want the help page to be in a new window. This is where we add a new function that will open a pop-up window when the help page is invoked.

mainMenuBar.jsp
This is where the Help button is located and a javascript function to invoke the online help documentation in a new window is identified. This jsp file contains all the buttons necessary to provide functionality for the user.

web.xml
We don't want the onlinehelp-config.xml file to be read each time we invoked the help pages. There's 3 ways to handle this file

1. Read this file, convert it to Java Bean/Map and put it in session.
2. Read this file, convert it to Java Bean/Map and put it in cache.
3. Read this file, put attributes in a Map and put it in a singleton object.

I prefer the latter for simplicity and less coupling though all of them promotes efficiency. If the bean is put in session we are introducing a tight coupling with the container's session implementation. If a third party caching mechanism is used then we are tied to that implementation.

In this example I used the third option and have a servlet intialize the class that reads this file which is called OnlineHelpProcessor (Singleton). The method called for initialization from this class is initializeOnlineHelpCodes(). Its just basically reading the file and putting attributes in a Map.

When the application starts up, the singleton class is initialized and all the elements from the config file is put into a Map ready for access anytime.

OnlineHelpProcessor
This class reads the onlinehelp-config.xml file and converts the elements into a key/value pair in a Map and provides a method that takes in a struts forward name argument and returns the onlinehelpcode value which is later used to load the right help page.

Tuesday, May 12, 2009

Using Chain of Responsibility Pattern

More than a year ago I was presented with a business requirement that has an accompanying process flow chart. The requirement  was basically validating an Insurance Agent. The following information were used to perform business rules/validation on a specific agent and see if he/she can do business at a certain area, or is able to use current authorization or if his/her current contract is valid. 

1. Authorization
2. Profile
3. Contract
4. Managing Agent

Looking from the document, there were sets of processes that contains business rules that needs to be performed but each process completion can lead to one or more possible processes to be run. This scenario is depicted below.




I chose a pattern to basically build the framework that will allow for easy integration of new processes into the mix and not complicate the validation implementation. If this is to be implemented without a framework, deeply nested if - else statements arises and increases cyclomatic complexity issues. The Chain of Responsibility Pattern seem to perfectly fit this requirement. This pattern comprise of several chains all link together and each chain is aware of if the request coming in is intended for it or not. If it is then it applies whatever process is needed on that request data. If not then it just passes the request to the next chain in the link. The process in the figure above is represented as a chain. In this case we have 9 chains in the link. 

Each of the 9 chains contains thick business logic validation implemetation that takes in an input and redirects the output to a different chain for further request validation. The process continues until one of the chains mark the validation process as completed and package the output data to whatever format the requester is expecting. 

This is the Class Diagram that reflects this design. In addition to the chain pattern, the Template Method Pattern was also used as can be seen from the hierarchy relationship of Chain interface, AbstractChain and its subclasses.


There are four things to consider from this diagram - Chain interface, ChainManager, AbstractChain and its implementation(chains).

Chain Interface
Defines the contract for implementing the methods add(Chain chain), processNext() and isLast(). The latter identifies a chain if its the last one to be executed. 

ChainManager
It is responsible for creating the chains, linking them altogether and kicking off the first chain. The pseudo code below shows this implementation.

Chain process1Chain = new Process1Chain();
Chain process2Chain = new Process2Chain();
Chain process3Chain = new Process3Chain();
Chain process4Chain = new Process4Chain();
Chain process5Chain = new Process5Chain();
Chain process6Chain = new Process6Chain();
Chain process7Chain = new Process7Chain();
Chain process8Chain = new Process8Chain();
Chain process9Chain = new Process9Chain();
DefaultChain defaultChain = new DefaultChain();

process1Chain.add(process2Chain);
process2Chain.add(process3Chain);
process3Chain.add(process4Chain);
process4Chain.add(process5Chain);
process5Chain.add(process6Chain);
process6Chain.add(process7Chain);
process7Chain.add(process8Chain);
process8Chain.add(process9Chain);
process9Chain.add(defaultChain);

// Assign the point of entry chain,
Chain entryPointChain = process1Chain;

//Kick of the first chain
entryPointChain.processNext();

AbstractChain
The process() method of this class reflects the Template Method Pattern. The power of polymorphism lies here. Its subclasses plugin the right logic at run time and these chains are decoupled from each other. 

As you notice the DefaultChain is included in the diagram. If you want to do some post-processing cleanup, provide the logic here.  

The beauty of this chain pattern is its extensible. From our example above, if we need to add another set of validation logic, all we have to do is create another chain and add it in the link and provide the business logic in its process() method. If a validation is no longer needed, just remove that chain from the link that implements the validation and the application should still run without any side effects.


Wednesday, May 6, 2009

When do we say its the right tecnology to use?

When is a technology the right tool to use? Do we influence the feature we want in an application from what is available from the technology or from what is required from the business requirement?

It's always a challenge to marry the right technology with the right requirement that would produce a fluid, solid application. One-Stop-Shop approach of resolving business issues is no longer becoming relevant in the global IT market. You pay so much that without realizing only a fraction of the features provided by that technology is only essential to what the business requires. A lot of companies now are resorting to only "get what you need" and "pay what you only need" mentality. This is where customization comes in. The beauty of customization is it delivers the solution that the problem it exactly expects. This strategy relieves companies from paying too much.

When the curse of overengineering starts to sink in, its a manifestation of wrong implementation. But what is overengineering? It's a combination of technology misuse and irrelevant complex implementation. If the implementation looks simple and it solves a business need then we just answered the first question above.

The danger comes when technology features molds how the application should behave. This deviates the application from concentrating into its prioritized functionalities and might deliver features not needed at all. Scope creep is the twin evil of this situation. Looking at it at the brighter side, this is the best opportunity to step back and review the requirements and correct and refine the implementation.

Implementing User Sessions for Crystal Reports Java SDK

If you are submitting requests for batch processing in Crystal Reports via its Java SDK, never login to the server per request. I've seen this implemented and it's just creating an unnecessary overhead. Here are the steps to create a session that would serve multiple requests.

1. Log on to Crystal Report Server

You call the metod CrystalEnterprise.getSessionMgr() which returns you an object of type ISessionMgr. From there call the method of the returned object below which returns an object of type IEnterpriseSession.

logon(String userName, String password, String ceServerName, String secEnterprise);

2. Create Logon Token

The IEnterpriseSession has a method getLogonTokenMgr() that returns ILogonTokenMgr. Call the method below to get the logon token string.

createWCAToken(String clientServerName, int validMinutes, int validNumLogon);

The validMinutes parameter represents how long do you want to maintain the session and the validNumLogon represents how many logons the client can perform in one session within the given valid minutes.

3. Logon to Crystal Server with Token

Call the method below from the class ISessionMgr and pass the logon token string that was previously generated. This returns to you a new IEnterpriseSession that has the token. All transactions will then use this session object until the minutes or log on counts are exhausted.

logonWithToken(logonTokenString);

Of course, somehow this session will expire later on and the client application need to reconnect. The good news is you just have to follow the same steps. On the other hand, if the session is still valid and somehow the application needs to reset the connection, always check for the session if it already expired. If it is, release the token and logoff with the following sequence then proceed to steps 1 through 3 again.

releaseToken(logonTokenString); // called from ILogonTokenMgr
ceSessionWithToken.logoff(); // called from IEnterpriseSession with token
ceSession.logoff(); // called from IEnterpriseSession without token

This approach will be very useful for batch processing. You want to keep the pipe full while the report server is processing. With on demand request report processing, you don't want to keep a session open for a long time.

Friday, May 1, 2009

Java Multithreaded Web Service Performance Tips

Right after Java 5.0 Concurrency Model was released, MultiThreaded Java Web Service application is always an interesting subject. It's easy to tweak codes that are slowing down the application. But it was always a challenge to tweak it at the container level.

A former colleague of mine and me worked to figure out why our Web Service Application was slowing down and always leaves lots of run-away processes. Here are some of the findings we had implemented to keep our application rolling! The sample codes below reflects a reporting process where requests to generate a report is made and how the threads handle the status of each requests.

Use Java Concurrency API
There are only three classes that I've used to implement a MultiThreaded WS Application.
Runnable, ScheduledExecutorService, and ConcurrentLinkedQueue. 

The ScheduledExecutorService implements ExecutorService and is of type Executor.  Executor is responsible for abstracting the gory details of implementing threads into simpler methods. And it works all the time.

ScheduledExecutorService allows you to provide what the initial time is to run the thread associated with it, at what frequency, the thread to run and the unit of time. Was very easy to use and you can configure the thread pool size as well. The application I wrote had 5 threads running concurrently and it never had any problems at all. They all shared the ConcurrentLinkedQueue object resource and I didn't use the synchronized keyword to make this object thread safe since by default it already is.


Using the Runnable interface is better than just extending the Thread class. It promotes less coupling. Here's a sample of how this thread is plugged-in to the ScheduledExecutorService.



Implement the ServiceLifeCycle
Implementing ServiceLifeCycle will allow you to put shutdown hooks and implement its destroy() method where you can manipulate how the spawned threads are to be shutdown/killed. The init(Object context) method must also be implemented.



Provide Shutdown Hooks
The shutDownMonitor() method is called and the ExecutorService's awaitTermination() method is invoked which basically gracefully shuts down the spawned thread in the WS Container according to the specified time (might be in seconds, minutes, hours). You can also force to shutdown all threads by calling the method shutdownNow() if it takes longer than the specified time.


Use "application" Scoping
When you use "request" scope as configured in your wsdd file, you are creating one instane of the service per request. If several requests were triggered, your application is also spawning threads per request. The previous request that was processed left a trail of run-away processes. If the scope was "application" it will create only one instance of the service that will serve multiple requests. Hence, when the application runs it does not create run away processes since we already have a shutdown hook to kill all of the spawned threads before the application completely shutdown.


I think it all depends on what an application is trying to achieve, it might have more complex business process than this sample code we have and it requires more classes to use from the concurrent api. But in a multithreaded web service application, you definitely want to use the application scope and implement a shutdown hook.

Tuesday, April 28, 2009

Jakarta Commons Net API

Jakarta Commons Net(JCN) Java Library is just one of those open source projects I've enjoyed working with. Specially its FTP API. Which is gonna be the focus of this discussion.

I've implemented a component that uses this library in a Web Service environment which basically connects to a remote FTP service then iterate through the list of directories, process the files and handle the reply codes properly. The list of files may go to several thousands. 

Here are the things I found really useful from JCN.

1. It automatically issues a new PORT command to the server so we don't have to worry about manually setting the port for different platforms (Unix, Linux, Windows, Mac, etc.) when connecting. Also validates data connections to client to ensure the request had originated from the intended host. We don't want our application deal with strangers eh?

2. It allows you to page through the list of FTP files. I think this is an awesome feature! From my previous project the list of files can span to several thousands. But through FTPListParseEngine class I was able to page through the files and process them in smaller chunks. This is a great performance boost. We only load the ftp file objects we currently need. Creating this objects are expensive. We keep the metabolism of an application running this way and saves us the evil of bottlenecks.  


3. Provides very easy to use and effecient way of handling FT Reply Codes. The codes are basically messages passed by the FTP Server indicating if the request was processed successfully or not. There are about 49 codes which you can check at this link http://www.turboftp.com/turboftp/manual/TURBOFTPFTP_Server_Reply_Codes.htm . After a command is issued to the server, the server returns an int value representing the code. Just capture this code and apply the behavior you want to happen in the application. 

This is a great way to isolate specific ftp issues and handle it properly so the application can still function, say even if the FTP service is down. Or if your previous request gave a code that identifies your request as not processed, you can resend it upto a certain number of times until you mark it failed. There's no point sending an ftp command or request if the data connection is not established, as shown below.


Also shown below is an example of flagging the reply if its ok or not with their matching simple behavior implementation.


I can see no reason why JCN can't be used. It provides the necessary security and performance gain we need. Plus it provides you an elegant way of handling FTP Reply Codes that you can use to manipulate the behavior of an application consuming an ftp service. Documentation is well written too.