Psychedelic Panorama of Foo

제 이름이 Inigo Montoya 입니다. 당신이 내 아버지를 죽였어. 죽을 준비해.

월요일, 4월 19, 2010



Here's my presentation I did for Java Day at ASU.

금요일, 4월 16, 2010


How would you describe your style?


Ask me anything

Ask me anything


How would you describe yourself in 3 words?

Not your banzai!

Ask me anything


Do you want to be buried or cremated?

C. Vaporized.

Ask me anything

목요일, 9월 03, 2009


Adding Encryption to Groovy Configuration Files

안영하세요. Last post, I explained how groovy could be used for configuration. Like any good programmer, I like to stick my code in VCS which includes my configurations. You may remember from my last post that passwords were in my configuration files. Now, it's just stupid to stick passwords in your VCS. We all would rather not do it. It's the easiest thing to do though. The only way to get away with it is to encrypt your passwords when you put them into VCS. The question becomes, "How do you decrypt them then?" I encrypted my passwords with RSA public/private key encryption. I then base64 encode the encrypted result for adding to VCS.

Here is an example

cfg = new NodeBuilder().cfg { db { url 'jdbc:oracle:thin:@localhost:1521:UAZKFCFG' ua { name 'ua' password decrypt('cfg', 'GHp6V73vu5Q4D9OR8SEoOFkstv0rqhJ97yTfgMAPnIjkbDIDZT9NBQIIvsy4sdRrXWju6ZFeG12tB3qVLdJOl3PlefeTq/KactkUVGU5Yv0iKQW19Wto7YVWMJUfwmI+Te/Nd+snLkhQixFBXoncjMAJF652+UIhwUiDHASn6GJ8McuiwjOvkUSTl1VLbOeF8zZu0DNzBzADic8M/Y4mbBT9aFtmgXfM2RZ8WxpT+7s475JAgieqp+gCUvskrn238zMCXEJvJgmk+de4u2mmYF6O1FZN/LzSyoh2NRLaKv4IU2Zz+U58DSLYUScIqIskWIxIRVSdibOLVUJZd8wSoOO2+DbS1/23FE55RzVjOXW7bJMTsTFhwpm4SaFt2kdoPVHxjVRKvagOKgj48ciT7gf4houRPlhG4kxD/piRax1sr8OLHGlv6ZxPBB6zVSw9WXL7S3sj9UNO6NGd0CccJXgOu8EqZyqV8lIJV1axSLuCye83RAoGYqDX9+x8msMotpfyDv+W/RHwb9ssmjhr8iCRK/8oxrhZO7yXVU7QJyuwelaGPzW+kQXTIvgLecO93mcr57Bh20GUXCEr2o3uFYh18+JRnoliLKfpAm7QrFw3xbiAmfulhnBXbGDjsCKvqXFnZFAZFkjbI1CT8yiDchobh/c2DxwyytLeNc4aIj4=') } } }

Notice I call a method called decrypt(). I pass in two values that are teh environment name and the encrypted password. I pass in the environment name because I have a separate public/private key for each environment entry. To distinguish them during decryption, I have to pass this value into my decryption method.

This is how the decrypt() method works

import import import import import import import import import javax.crypto.Cipher; DEFAULT_CIPHER = "RSA/ECB/PKCS1Padding"; KEY_FACTORY_TYPE = "RSA"; SSH_DIR_PATH = System.getProperty('user.home') + File.separator + '.ssh' + File.separator ... ... String decrypt(String environment, String pw) { def key = getPrivateKey(environment) cipher = Cipher.getInstance(DEFAULT_CIPHER); cipher.init(Cipher.DECRYPT_MODE, key); return new String(cipher.doFinal(pw.decodeBase64())); } PrivateKey getPrivateKey(String environment) { def keyBytes = new File(SSH_DIR_PATH + "kfs_$environment").readBytes() def spec = new PKCS8EncodedKeySpec(keyBytes); def keyFactory = KeyFactory.getInstance(KEY_FACTORY_TYPE); return keyFactory.generatePrivate(spec); }

There you go. Encryption of values in the configuration file. With this, you wouldn't just be able to encrypt passwords, but whatever you want to securely store in your VCS from your configuration. I feel like the guy from lifelock! Enjoy!


Groovy's NodeBuilder for Configuration File Notation

I have always liked the way ant uses java properties files for configuration options. I also liked the convention of separating contexts within the property names by '.' I wanted to do something similar in groovy, but found that whatever I came up with always fell short because ant offered property validation. That is if you referred to a property that wasn't set or misspelled a property name, ant was all too happy to let you know. If you want that in groovy, you find yourself using AntBuilder. That practically means you're using ant at that point. I wanted something more native to groovy that would validate, have structure for contexts (hierarchical even), be modularly inclusive (that is I could reuse the configuration), and I wouldn't have to build much infrastructure for it.

Praise be to God!! NodeBuilder! Here is an example of how I create a configuration that represents my rdbms

cfg = new NodeBuilder().cfg { db { url 'jdbc:oracle:thin:@localhost:1521:UAZKFCFG' ua { name 'ua' password 'secret' } kulowner { name 'kulowner' password 'secret' } } }

You can see it creates a hierarchy. I don't have to redefine the 'url'. I can have multiple schemas attached to the url. It's great. Now how do I use this in my groovy code? Here's that example.

evaluate new File('config/environments.gv') ... ... cfgTableDb = Sql.newInstance(cfg.db.url.text(),,, ORACLE_DRIVER_NAME) targetDb = Sql.newInstance(cfg.db.url.text(),, cfg.db.kulowner.password.text(), ORACLE_DRIVER_NAME)

You can see that I use evaluate() to load the configuration as normal groovy code within my script. I am then able to access the NodeBuilder instances and pass the values in to Sql.newInstance(). The best part is it's native groovy. It's not a String. If I misspell something, groovy will let me know with a compile error. Man I love this language!

수요일, 9월 02, 2009


Console Progress Bar in Groovy

안영하세요! Recently, I've been doing a lot of work with ETL (Extract, Transform, Load) scripting. I've found that groovy is an ideal language for ETL. That's not what this blog is about though. Typically, when loading data into a database using java, ruby, groovy, etc..., you don't know how far along the load is. You only know when it finishes. Lately, I've needed to load 30k+ records at a time. This can take a pretty long while to do. Sometimes, I really want to know how far along it is. In SQL, this would be an impossible feat, but with groovy, it's quite easy.

Below is some example code for a progress bar. The trick is in \r which moves the print cursor to the front of the line without a newline:

def template = "\r|%s| %s" def progressLength = 70 def progressRatio = progressLength/100 for (i in 0..max) { def percent = (int) ((i/max) * 100) def progress = (int) ((i / max) * (100 * progressRatio)) def progressBuffer = new StringBuilder() for (x in 0..progress) { progressBuffer.append('=') } for (x in progress..progressLength) { progressBuffer.append(' ') } print String.format(template, progressBuffer, "${percent}%") } println ''

If I want to use this in my ETL, here's an example:

def insertStatement = targetDb.getConnection().prepareStatement(insertBuffer.toString()) int recordCount = 0 def template = "\r|%s| %s (%d/%d) records" def progressLength = 50 // This is the length of the progress bar in characters. Adjust to the size of your console as appropriate. def progressRatio = progressLength/100 println "Copying records " sourceDb.eachRow(sourceQuery.toString(), { sourceRow -> for (i in 0..columnNames.size()-1) { insertStatement.setObject(i+1, sourceRow[i], getColumnTypeByName(sourceMd, tableName, columnNames[i])) } insertStatement.execute() recordCount++ def percent = (int) ((recordCount/totalRecords) * 100) def progress = (int) ((recordCount/totalRecords) * (100 * progressRatio)) def progressBuffer = new StringBuilder() for (x in 0..progress) { progressBuffer.append('=') } for (x in progress..progressLength) { progressBuffer.append(' ') } print String.format(template, progressBuffer, "${percent}%", recordCount, totalRecords) }) println "...done. $recordCount records migrated" insertStatement.close()

There you have it. It copies records from one database table to another and gives the progress of that copy. Here is the example output.

Migrating table CA_A21_SUB_ACCT_T with 182 records Truncating table CA_A21_SUB_ACCT_T Copying records |=================================================== | 100% (182/182) records...done. 182 records migrated Migrating table CA_ACCOUNT_EXT_T with 20826 records Truncating table CA_ACCOUNT_EXT_T Copying records |= | 1% (292/20826) records

태그: ,

금요일, 6월 05, 2009


Scale of Experience Based-on X-Men

안영하세요. We are doing training proposals here at UITS. In doing so, I came up with a scale based on X-Men characters to gauge a person's experience level.

  • Rogue: Sucks in knowledge and absorbs powers of other mutants
  • Wolverine: Savage and unrefined level of experience. Crude, but more than effective.
  • Cyclops: More refined...and destructive. With leadership skills and ability to train others.
  • Magneto: Controls forces around them. Able to manipulate area according to his/her whim. Attracts worshipers and zealots. Able to form small armies of minions to do work for them by simply coming into work.

토요일, 3월 28, 2009


Setting Up Motorola E80 Paired with Linux for Internet through T-Mobile Web

Taken from Howard Forums

Connection Name:tzones
Data bearer:Packet data
Access point
User name:N/A

Advanced Settings (Handsets not equiped with WAP 2.0 may skip this section)

Proxy serv address:
Proxy port number:8080

We need to find the bluetooth ID of the phone. You can get it with either hcitool or hidd:

% hcitool scan % hidd --search
Or just type "*#2820#" on your phone. For the rest of this document we'll assume we're given a bluetooth ID of "11:22:BE:EF:44:33". Either way, you need to pair the phone. I had some problems here initiating the connection from the linux box. This command should work:
% hidd --connect 11:22:BE:EF:44:33


토요일, 1월 17, 2009


Origins of Leonard: Lionhart

I found this about my name at Leonard.

[ 2 syll. leo-nar(d), le-ona-rd ] The boy name Leonard is pronounced as LEHNerD KEY. Leonard is used chiefly in the English language and it is derived from Germanic origins. Two-element name derived from the elements 'leon' meaning lion ; 'hart' meaning brave, hardy. The name was borne by Saint Leonard of Noblac (-559), who was a Frankish noble in the court of Clovis I. It was also famous from the Italian Renaissance artist and scientist Leonardo da Vinci (1452-1519). The name was brought into England by the Normans, but did not appear commonly in the Middle Ages. It later enjoyed a significant revival in the 19th century. It is now also used by Jews. The name Leonarda (English) is the female form of Leonard.


This page is powered by Blogger. Isn't yours?

에 가입 게시물 [Atom]