Monday, August 5, 2013

Connecting to DB2 with Ruby on Linux

Recently got my hands dirty with ruby, my first task. Ya I know I am quite late to work on quite popular dev tool. Anyways, task was to access +IBM DB2 from +Ruby  (without using rails). If Ruby, DB2 was not complicated enough, the added complexity factor came from Linux and that too RHEL (not ubuntu). 

Started with low hopes

  1. Installed latest version of Ruby:
    curl -L https://get.rvm.io | bash -s stable –ruby
  1. Installed and verified the ibm_db gem
        
  1. You will need a DB2  installation – I used DB2 express 9.5 (on a separate machine)

  1. Now I needed a DB2 driver on my main machine. So searched and installed “The IBM Data Server Driver for ODBC and CLI product”. Nice instructions here

  1. After unzipping the driver in the previous step set the environment variable:
    export IBM_DB_HOME=path/to/odbc_cli/clidriver
       
  1. Now install the gem, (Some nice pages to install/configure ibm_db gem here) from command prompt
    gem install 'ibm_db'
  1. Export another variable:
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/odbc_cli/clidriver/lib

Verify the install and connection:

  1. On Command prompt give command:
    irb require 'ibm_db'
    you should get “true” as response
  1. Now give this command
    IBM_DB.connect('DRIVER={IBM DB2 ODBC=DRIVER};DATABASE=devdb;HOSTNAME=myhost;PORT=60000;PROTOCOL=TCPIP;UID=uname;PWD=password;','','')
    
    you should see something like this => ibm_db::connection:0x2dddf40>
    Note that on giving this command it will connect to your db2 on the mentioned port, if     this DB2 is not on local machine then firewall can block the inbound connection, so on the db2 machine make sure to accept the connection or configure firewall if any manually.
  1. Now:
    stmt = IBM_DB.exec conn,'select * from staff'
    Here I started getting an error undefined symbol: rb_str2cstr. Searched on the web, many result for sqllite but not for db2. One thing was clear that there is some version problem. Finally raised a bug at rubyforge. Again little hopes, but was amazed by the turn around time and also the exact solution. Though it required to make some changes to the ibm_db file. (which should be fixed as part of the the gem itself.) Anyways, the solution was:
    a) cd .../gems/ibm_db-2.5.11/ext
    b)In extconf.rb, replace "if( RUBY_VERSION =~ /1.9/)" with "if(RUBY_VERSION =~ /2.0/)"
    c) ruby extconf.rb
    d) make && cp ibm_db.so ../lib/
    

    Again gave the stmt command and this time the result was “false”. No error description, nothing. How come people make such software and even distribute. Just by chance stumbled on another command “prapare”.  
    stmt = IBM_DB.prepare conn,'select * from staff'
    This time got proper error (there was some issue in qualifying the table name with proper user). Corrected the stmt exec command.

  1. Final command
    IBM_DB.fetch_assoc stmt 
    
    and got the result :)

Thursday, July 11, 2013

Shiro with Spring: Remember Me - Custom Cipher Key

Recently was working with Shiro apache security library. Nice library with good inbuilt methods like “Remember Me” function.
You just need to set the value at the time of login and it will take care of rest. There is a small caveat, this functionality uses a hardcoded AES key to encrypt the user name. More information here: http://shiro.apache.org/configuration.html#Configuration-ByteArrayValues

As the article rightly mentioned you can specify your own key in the shiro configuration ini file. Ok, I did the same but in my project we were using Spring to configure Shiro so instead of specifying the key in shiro.ini, I specified it in my properties file, which was read by the spring config file. Sample code: In spring config file:

<bean id="securityManager"  class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
<property name="subjectFactory" ref="mySubjectFactory"/>
<property name="rememberMeManager.cipherKey">
<value>Your Key</value>
</property>
</bean>

All worked fine, the key was picked up but my test cases started failing. 

Downloaded the source for Shiro, debugged the flow and found that Key picked properly, also getting read in the AbstractRememberMeManager. After lots of wasted hours, found that there was exception from a Java class while encrypting user name. (invalid key length) . Come on I was using the same code to generate the key as mentioned in the comments of default cipher key.
(More wasted hours)
Finally did something basic, provided the default shiro cipher key in the properties file and again error. That made one thing clear – There was some issue in how the key was read/set.
(why I didn't find that while debugging, because the key is actually set as byte array and me being proficient only in English and Hindi couldn't notice the difference in byte representation :))
Ok, now where is it getting corrupted. Downloaded the spring libs’ code and found that the key received by the shiro class was getting corrupted in the spring code itself. On further investigation found that instead of using Base64.decode, spring was converting the key (which was encoded to string with Base64) to bytes directly (but of-course).
Looks like while reading from Shiro.ini file this is taken care of by shiro, but when using spring, one needs to make sure that key is set in the security manager after getting decoded to byte using Base64 only.

Huff, problem found, solution was much simpler. (no you cannot use spring's ByteArrayPropertyEditor it again does not use Base64)

Create a custom property editor.
1) Create a java class:

import java.beans.PropertyEditorSupport;
import com.ibm.xml.crypto.util.Base64;
public class BytesPropertyEditor extends PropertyEditorSupport {
    public void setAsText(String text) throws IllegalArgumentException {
        byte[] bytes = Base64.decode(text);
        setValue(bytes);
    }
}

2) Add following in your spring config:
<bean id="customEditorConfigure2"
    class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
            <entry key="byte[]">
                <bean class="com.amit.BytesPropertyEditor">
                </bean>
            </entry>
        </map>
    </property>
</bean>
And you are done. Happy remembering me... *_^

Wednesday, July 3, 2013

How I broke my Linux (RHEL) and fixed it

Few months back I moved to RHEL Linux and managed to crash the OS by doing seemingly safe things. Here I am sharing my experience with other users so that they don't end up wasting time like me.
What I did
Installed XFCE and then uninstalled it
Why
I was hoping it to be better than gnome in terms of user experience. Later found its actually minimalistic desktop mainly for low end systems.
What happen
System failed to boot. Failsafe boot option also didn't work.
How I fixed
Reinstalled Gnome desktop by booting to RHEL command
  1. Boot to Red Hat command line (steps in 'how to' below)
  2. Ensure the network is working (steps in 'how to' below)
  3. Reinstall gnome by giving command
              Yum groupinstall “GNOME Desktop Environment”

Should you try it
You can of course try XFCE but if you uninstall make sure to install Gnome Desktop again before any sort of reboot. I haven't tried this but based on my experience this should prevent the OS crash on next reboot.

Below are few ‘how to' which might be useful in case of system crash:
How To 1: How to boot RHEL to command prompt (not the grub menu)
1. Boot/reboot machine
2. At blue Red Hat screen press any key to enter the boot loader
3. Press 'e' to edit the most recent boot command
4. Use the arrow keys to select the line that starts with "kernel"
5. Press 'e' to edit the kernel command
6. Append 'S' to the end of the line. There should be a space before the previous end of the line (probably 'quiet') and the 'S'. Capitalization matters.
7. Hit Enter to commit the change
8. Hit 'b' to boot
9. When it is done booting you will be at a command prompt. Type 'help' for list of available commands

How To 2: How to connect network in the command line mode
Once you get the command line it's of no use if you have to install something and you are not on network. To start network (assuming that whatever you did to crash your system, it didn't mess up your network settings)
dhclient eth0

Note:
  1. I am pretty sure that other people might be having similar inputs so feel free to put in the comments.
  2. The reason/solutions mentioned are based on my search on internet, in case someone has anything to correct/add, please feel free to point out.

Monday, July 1, 2013

Lotes Notes tip: Upgrade notes database version

If you are using lotus notes and upgrading from past versions, chances are you might be using an old database version, most probably will be 43. Notes database version should be 51 assuming you are at 8.5.3 or above

To Check: Application -> Properties -> i and look for ODS version  

1) How to fix: Add following in the notes.ini
NSF_UpdateODS=1
CREATE_R85_DATABASES=1

2) Do a compact on the database (Application -> Properties) . To compact all the databases, simply fire compact -c from command prompt from your notes directory. (Looks like -c option to convert is necessary, for me the GUI option didnt work for archive files which were not store in the notes/data directory. To convert those I used compact -c )

Result:
  1. More compact database.
  2. Better speed
  3. Ability to use newer features of the new db version

Thursday, June 27, 2013

Dependency Visualization - Finding the missing link

Ok bit late but here is the link to my Dev works article, hope you would like it:

Dependency Visualization - Finding the missing link

Summary:  In OSGi framework, the bundles clearly specify what they provide and what they need, but finding these dependencies manually can be difficult. That's where the Dependency Visualization tool comes in...