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.