How to Conquer the Atlassian Dragon

I decided to document my attempt at slaying the Atlassian “Dragon” in Atlassian’s Here Be Dragons challenge.  Atlassian is a software company, that makes bug-tracking, collaboration, and software management company with products aimed at software development teams, specifically those using agile methodologies.  Since they are near the top of the list of companies I will apply for in the next few months I thought I should familiarize myself with their product line as well.  I documented everything I did in case anyone wants to follow in my footsteps. I set up a Linux virtual machine using Oracle’s VirtualBox platform which runs on Windows, Linux, and OSX, and allows anyone to follow along if they like!  Warning: this is a fairly long article.

The quest begins with:

Beware, all ye who enter, for here be dragons! This is the starting point for the Atlassian Dragon Quest.

It involves setting up Atlassian’s main set of products:

Atlassian allows setup of their products on most operating systems, and supports many different databases for the back-end persistent data management.  Since they allow complete setup on Linux, I choose that route mostly to force me out of my Windows comfort zone.  I created a VirtualBox virtual machine running Mint Linux 11.  It took me longer than Atlassian’s expected 4 hour completion time since I also documented everything I did.  Here was my rolling documentation over the whole process:


Setup:

To begin virtual machine (VM) setup I have downloaded the latest version of VirtualBox (version 4.0.12 at the time of writing this) and have downloaded a distribution of Linux I had recommended to me by a friend last year called Linux Mint 11 (I downloaded the the 32-bit DVD ISO file).  Mint Linux is a derivation of Ubuntu Linux that includes several non-open source codecs, something Ubuntu does not like to include by default due to its “open source only” ideology.  I’m all for open-source, but that’s a topic for a different article.

Mint Linux VM Installation:

I have officially begun!  I have tweeted my status and am installing the Mint VM on VirtualBox.  Atlassian says I’m going to need ~2GB of ram on the VM to run everything so I’ll setup the VM with their recommended setup.

VirtualBox settings for anyone following in my footsteps:

  1. New (button)
  2. Name your virtual machine (named mine MintLinux11), operating system: Linux, version: Ubuntu
  3. Memory: 2048 MB
  4. Create New Disk (start-up disk checked)
  5. VHD file type since it is compatible with VirtualBox and I believe several other virtualization software platforms
  6. Dynamically Allocated
  7. Allocating 10GB, but I don’t think it’ll go much above 5
  8. Create VM

On the main VirtualBox screen:

  1. Select VM and select Settings (button)
  2. In the Settings Menu, select the Storage item (1)
  3. Under the storage tree mount the MintLinux11 ISO downloaded from Mint Linux’s website (press the disc icon with the + sign (2)).  Here’s a screenshot with items circled:
    VirtualBox ISO Mounting
  4. Press OK, then Start (button) the new virtual machine

Linux Initial Setup

Linux will start in an evaluation mode, but we want to completely install it.  Double click the “Install Linux Mint” disc icon on the desktop.  Installation is as straight forward as possible (next next next next finish).  Make sure to select the “Erase Disc and Install Mint Linux” option–no worries it only sets up the 10GB virtual hard disk setup earlier.  The VM installation process will take roughly 10-20 minutes depending on your computer’s capabilities.

When installation is complete, Mint will prompt you to restart, click restart.  After restarting, you will need to unmount the ISO image you installed earlier.  In VirtualBox menu bar, select: Devices > CD/DVD Devices > IDE Controller (IDE Primary Master) > Remove Disc from Virtual Drive.  Select enter to complete the restart of the virtual machine if prompted to do so.  If you end up back at Mint Linux’s login screen, you’re ready to go!

Mint Linux

Guest Additions:

The Virtual Machine is setup and installed, setting up the desktop environment is the next step: VirtualBox guest additions first.  Guest additions provide a more streamlined integration between your computer’s regular operating system (known as the “Host” operating system) and the virtual machine operating system (known as the “Guest” operating system).

In the VirtualBox menu, select Devices > Install Guest Additions… Press Ok on the autorun prompt, then Run.  Enter the password you used when setting up the virtual machine, let the guest additions install.  Perform a quick reboot by going to Mint’s Menu > Quit > Restart.

Once restarted, your virtual machine should now resize the desktop whenever you reszie the virtual machine window!  Neat.  Guest additions also provide better mouse support, graphics support and more.  Read here if curious.

Last thing to do is make sure all of your operating system packages are up to date.  Right click your virtual machine’s desktop, and click “Open in Terminal”.  Type sudo apt-get update, then press enter and type your password.  After the update, type sudo apt-get upgrade, and enter Y when prompted to do so this will upgrade all system packages making sure your operating system is fresh and ready to go!  This last will take ~15 minutes.

Pre-JIRA setup:

Java and PostgreSQL:

Java: Done.  Ok, using Mint Linux is sort of cheating since Java comes pre-installed.  Verify the installed version of Java is compatible with JIRA just to be safe by opening a terminal (right click desktop > Open in Terminal, remember?) and type java -version.

PostgreSQL: This is a tid trickier than the previous step.  We’ll install PostgreSQL and pgAdmin3, the database and management tools that the Atlassian instructions have us use.  Open the terminal and type sudo apt-get install postgresql postgresql-client-8.4 postgresql-client-common pgadmin3 and press Y and type enter when prompted to do so.  After installation completes (~3 minutes) you’ll need to setup the postgres user login info.  First type sudo passwd -d postgres to reset the postgres password, then type sudo passwd postgres and set the postgres system user’s password to password.  Set the postgres database password by typing sudo su postgres -c psql template1 and enter the SQL command ALTER USER postgres WITH PASSWORD ‘password’; to set the database login password, then type q to quit SQL entry mode. Last we need to set the database to allow password authentication by editing it’s pg_hba.conf file.  Type sudo gedit /etc/postgresql/8.4/main/pg_hba.conf, scroll to the bottom and change the last lines to have everything use password authentication.  Changes in bold below (change “ident” to “md5”):

# Database administrative login by UNIX sockets
local   all         postgres                          md5

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD

# "local" is for Unix domain socket connections only
local   all         all                               md5
# IPv4 local
 connections:
host    all         all         127.0.0.1/32          md5
# IPv6 local connections:
host    all         all         ::1/128               md5

Almost done!  Restarting the database for the authentication changes to take affect.  Type: sudo /etc/init.d/postgresql restart

Lastly, verify the setup by opening pgAdmin3, the PostgreSQL database management software.  Type pgadmin3 & and press enter in the terminal.  Click the plug button to connect to the database installation, enter information as shown here:

Register Database

When finished press Ok.

Everything from here is much more straight forward since this is really where the Atlassian guides have explicit instructions.

Setup database login role and database:

Expand Server Groups > Servers > pgdb.  Follow the instructions on Dragons Stage 1.

JIRA installation:

At the time of writing this, JIRA 4.4 is out so I will be installing that according to Atlassian’s Dragons Stage 1 instructions.  Carrying on, I have downloaded JIRA from the download site.  When downloaded you’ll receive a file called atlassian-jira-X.X-x32.bin (make sure to download the 32-bit version, X-X is the version number you downloaded).  Right-click the folder and open the folder in terminal.  We need to allow this file to be executed so enter sudo chmod 755 *, then type sudo ./atlassian-jira-X.X-x32.bin (where X-X is the version of JIRA you downloaded).  Install JIRA with all defaults.

JIRA setup:

Navigate to http://localhost:8080/ (the default JIRA installation location), and follow the JIRA setup instructions very closely!  On the computer name step, select the name of the VM.  This can be found by typing cat /etc/hostname in the terminal, and make sure to keep it in mind since you use it in nearly every product setup step.  Also, you will need to create an Atlassian account (if you do not already have one) to generate evaluation keys for each of the products you will setup during the Here Be Dragons challenge.

Setup project and create JIRA database:

Continuing on I’ve setup the use groups, created the project, and added the initial issue!

Greenhopper setup:

Extremely straight forward setup!  Finished the instructions in ~ an hour.  I setup Greenhopper and have created the extra issues.  I even created a SCRUM issue.  I’ll have to look into what exactly the SCRUM methodology is another time though.

Confluence setup:

3.5.7?  I wanted to try the new Confluence 4.0, but I guess I’ll have to wait for now.  Onward!  I begin with the Confluence instructions.

Here, I didn’t finish the night I meant to, and left for a brief vacation before sitting down to finish.  😉

Finally finished.  It only took 14 days. 😉  Again everything was very straight forward.  🙂

FishEye and Crucible setup:

The first step says to get Mercurial and Python setup.  Mint 11 has Python 2.7.1 installed, but Mercurial is not.  Unfortunately the python headers and setup tools are needed to build things, and are not installed by default.  This can easily be remedied by running:

sudo apt-get install build-essential gcc python-dev python-setuptools

Then you install python’s docutils by entering this command:

sudo easy_install docutils

and finish by installing mercurial.  Download it from Atlassian’s recommended download site (I downloaded 1.9.2).  Then finish by extracting the downloaded tar file, change directory to the extracted file, and run:

sudo make install

Type “hg” to verify the installation went smoothly.

Create the .hgrc file in your Mint user’s home directory by opening a terminal window, typing cd ~ then type gedit .hgrc .  Add the contents mentioned in Atlassian’s instructions in the first step.

Everything else was pretty straight forward.  To set the FISHEYE_INST environment variable, enter this in the terminal before starting up Fisheye (change the directory if you didn’t install to /opt/fisheyecrucible):

FISHEYE_INST=/opt/fisheyecrucible
export FISHEYE_INST

Get JIRA and Fisheye Talking:

This one was straight forward and a piece of cake!  Nothing can really give you too much of a hangup.  The dragon is coming along nicely!!

Get JIRA and Crucible Talking:

Another easy one!  Woohoo.  Got the dragon all Crucibled up!

Install Bamboo:

Again, getting Maven 2 is pretty easy with Mint, just download it from the APT repository by typing this into the terminal window: sudo apt-get install maven2

After, you will need to set the M2_HOME and JAVA_HOME environment variable.  As before, type:

M2_HOME=/usr/bin/mvn
JAVA_HOME=/usr/bin/java
export M2_HOME
export JAVA_HOME

These instructions seemed like they needed a bit of fixing, but the default IP address values seemed ok (127.0.0.1).

In step 6, set the JDK to JDK 1.6.

Bamboo Gadgets and JIRA Victory:

Adding the two gadgets are easy!

Summary:

Conquered the dragon!
Conquered the dragon!

I’m done!  I got the VM setup, installed all of the products in the challenge, and best yet, I got a free t-shirt to show off my dragon conquering prowess!

Dragon Slayer!

I hope this has helped fellow dragon conquerors.  Please feel free to leave comments or questions!

How to Feed a Developer – Challenge Accepted: DiGiorno Toll House

DiGiorno Pizza AND Cookies
Pizza, Meet Cookies

You can only pass by the freezer isle and see something this ridiculous before one night you stop, and go “yep, this is happening, I’m going to do this.”

Make Friday Night Memorable!
This settles it!

But is it:

Pizza, and cookies?

          Pizza. And cookies?

                    Or

                              Pizza and cookies?

These are the decisions you are left with.

Let me see the nutrition information:

Pizza Nutrition
Really? 5 slices?
Cookie Nutrition
One cookie? Who eats only one cookie?

Pizza, and cookies:

Calories: 2 slices, 2 cookies: 680, + 180 = 860
Cholesterol: 2 slices, 2 cookies: 60, + 10 = 70
Sodium: 2 slices, 2 cookies: 1940, + 160 = 2100

Now the pizza. And cookies:

Calories: 2 slices = 680. 2 cookies = 180. Total: 860
Cholesterol: 2 slices = 60.  2 cookies = 10. Total: 70
Sodium: 2 slices = 1940.  2 cookies = 160. Total: 2100

When you think about it, they’re the same when you eat the pizza first, then the cookies at a later time, or when you eat the pizza and the cookies in the same sitting, but what if…

Pizza AND Cookies?!

Calories: 2 cookie-slices = 860
Cholesterol: 2 cookie-slices = 70
Sodium: 2 cookie-slices = 2100

Yep… cookie pizza:

Pizza Cookie

Oh man, that was… interesting.  Not recommended more than once though.  Now I need to clean up.  I’ll throw away the box.  But wait, what’s this?!

DiGiorno - Try All 3!
...At the same time?!

To be continued…? 🙂

A Neat Java WindowAdaptor Trick

I discovered this neat trick when I was trying to have a status bar get updated with an element when a Java dialog box gets created (JDialog).   The element in the status bar gets removed when the dialog box is closed.  This is handy, and also gives an example of the order that listeners get added with creation of Java GUI elements.

    //... JDialog box initialization code ...
    StatusBar.addTemporaryElement(temporaryElement, this);
    //... Rest of JDialog initialization ...
    //... in StatusBar class (extends JFrame)
    public void addTemporaryElement(JComponent temporaryElement, JDialog dialog)
    {
        //example, adding a temporary label or button to the status bar frame
        add(temporaryElement, JFrame.RIGHT_ALIGNMENT);
        dialog.addWindowListener(new MyWindowListener(temporaryElement));
    }

    public class MyWindowListener extends WindowAdapter
    {
        private JComponent tmpElement;

        MyWindowListener(JComponent tmpElement)
        {
            this.tmpElement = tmpElement;
        }

        @Override
        public void windowClosed(WindowEvent e)
        {
            remove(tmpElement);
        }
    }

Get All Phone Numbers From All Word Documents

There is a common question in interviews where you have a directory structure containing, lets say word documents, and you’re looking for all of the phone numbers in all of them.  I decided to poke around and devise a solution to this problem (credit goes to this post for getting me started).

Searching raw text files for phone numbers are easy, but word documents are slightly harder since they are in a compressed binary file.  I found a neat SourceForge project called docx2txt, a handy little Perl program that converts .docx files to easily searchable text files.  A bit of setup is needed to configure the unzip program location in the doc2xtxt.config file, but that’s it.  🙂

Warning, doing this in Windows is a bit more difficult than Linux since you’ll have to download Perl and cygwin to run my solution.

My solution:

Get/setup docx2txt from SourceForge, cd to the root of the folder containing the .docx files, then run this:

$ find . -name "*.docx" | 
      xargs -i perl c:/downloads/docx2txt-1.0/docx2txt.pl {}; 
      find . -name "*.txt" | 
      xargs -i cat {} | 
      grep -ohP "(?b[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}b" | 
      sort -u

Voila!  Yikes…

This is a long, multi-part statement though.  Here’s a bit about each part:

  • find . -name “*.docx” –> recurse through all directories, starting at current directory, and find all *.docx files
  • | xargs -i perl d:/Users/brian/Downloads/docx2txt-1.0/docx2txt.pl {} –> for each .docx file found from the previous statement, pipe it as an argument into docx2txt.pl
  • ; find . -name “*.txt” –> wait for the previous statement to finish, then find all of the generated .txt files from the second part
  • | xargs -i cat {} –> output the contents of each text file
  • | grep -ohP “(?b[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}b” –> search for all phone numbers of the format ###-###-####, (using -‘s, .’s or spaces for separators). Regular expressions are not fun, but made a lot easier by tools like Just Great Software’s RegexBuddy
  • | sort -u –> finally output each of the phone numbers (removing duplicates)

You should end up with something like this:

$ find . -name "*.docx" | 
> xargs -i perl c:/downloads/docx2txt-1.0/docx2txt.pl {};
> find . -name "*.txt" |
> xargs -i cat {} | 
> grep -ohP "(?b[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}b" | 
> sort -u
(888)555-0003
888-555-0001
888-555-0002
888-555-0006
888.555-0005
888.555.0004

What’s the Last Thing You’d Think Of?

Thinking from an airplane window
Airplane flights are good times to think

I have a fun mental exercise I like to run through called “what’s the last thing I’d ever think of.” It falls along the lines of the Zen Kōans (eg: “what is the sound of one hand clapping”), but find it helps me open my mind when I feel like I’m too deep in a project. It’s something I like to do when relaxing on the back porch, or sitting in an airplane like I’m doing now. It’s a fun activity to pass time that obviously can never be completed because you can always find something more obscure than your previous thought.

I used to try to think of the last thing I’d ever think of at the most intense times in school, so even during my high school graduation I tried to force myself to remember something totally far away (time and/or distance), like what the blender at home would be experiencing at that very moment, or little newts my sister and I used to find under rocks in my backyard in Virginia. Even though importantly seeming events are going on around me, or a problem I am thinking of is consuming my every thought, things like blenders at home and amphibians under rocks in back yards in Virginia still exist.  Maybe next time you’re stuck on a problem, try to broaden your thoughts to give your brain a chance to relax, then refocus itself on the problem from a different angle.

Human Readable Code

I recently got my virtual wrist slapped when a developer asked about good coding practices, and I over-generally recommended that he should “comment like crazy”. Immediately I received several responses implying that comments are evil, and that truly well written code should need little or no comments to explain what the code is doing, and the variable and function names should do most of the explaining. Could this be correct? Some people even say that inline comments are a sign of code smell.  In school, we were forced to heavily comment all code in our introductory classes, and once in upper-division, no longer required, but strongly encouraged to do so. Good comments were always brought up when lectures briefly mentioned coding styles and standards. How then, would very readable but non-commented code exist?

I did a brief Google search on “Human Readable Code”, and was delightfully impressed when I discovered a brief excerpt from Joshua Kerievsky’s book Refactoring to Patterns.  In this excerpt, he uses some code written by Ward Cunningham which gives the perfect example of human-readable code:

november(20, 2005)

Afterwords Kerievsky goes on to generally state that human readable code:

  • Reads like spoken language
  • Separates important code from distracting code

His example is beautiful!  It perfectly illustrates what perfect human readable code is (assuming the function returns a Date object initialized to Nov. 20th, 2005).

However, I have never seen production code like this.  I wonder why, look around at work, and it is obvious.  When would the average production programmer have time to write and rewrite function names so that someone unfamiliar with his work (or even them 12 months later) could view the function and know at a glance exactly what was being done?  Kerievsky’s example above is extremely beautiful code, but simply that he has a november function implies there are most likely january, february, march, april, may, june, july, august, september, october, and december functions as well.  Realistically though, it is just bad code.  Though descriptive, it will never be used in production environments.  I wont get into the potential headache that could arise from having to refactor each of these functions if the underlying code of each function had to be changed.  What I did notice is that Kerievsky said that the above code is nicer than this:

java.util.Calendar c = java.util.Calendar.getInstance();
c.set(2005, java.util.Calendar.NOVEMBER, 20);
c.getTime();
While that is certainly true, production coders just don’t get into the proper states of mind to write the best, most human readable name for the function.  The problem with function names is that they need to be specific enough to be able to be understood by other people reading/using the code, but vague enough that it can be used for multiple purposes (such as getting any date).  Most programmers would wrap the above code in a function like this:
Date getDate(int year, int month, int day)

While the november(20, 2005) sample is a perfect example of human readable code, the getDate example will be seen over and over again simply because it is good enough.  The problem arises when method names that need to be generic (specifically thinking of functions declared in interfaces or headers) which contain something along the lines of establishConnection() or initializeVariables().  These names are nearly always too generic, usually require them to do so.

Enter the comment!

Comments not only increase code’s human readability, but are essential to it.  I firmly believe that stigmas against commenting arise from comments like this:

//initialize the variables
initializeVariables()

That’s just nasty.

I propose a solution: Write comments before you even begin programming.  Describe exactly what you are about to do in your code both to yourself and to the future code maintainer who will see the code (and may even look back at the source-control revision control system logs to see which developer wrote this, and is punishing them from months/years before, who may even be yourself :D).  After your first draft, rewrite it in as short and concise language as possible, summarize what you are going to do into actionable steps or verbs.  Finish off by filling in the code.

This method absolutely should be done before you write any code.  It will work much better because your “English brain” is still capable of coming up with complete intelligible sentences, and your engineer brain hasn’t quite taken over.  Furthermore, it will be much more readable in the future when you have to come back to try to find what went wrong or got overlooked.  If you start commenting after writing code, you are likely to write comments like the one above.  Write what you mean to do in comments first in human-readable English, then start programming.

I feel like this article would benefit from a trivial example, so this is a C# function I wrote for my server-side development class to parse Twitter-like “mentions” of a user out of a users’s string (ie “blah blah blah @brianesserlieu“):

Phase 1 – write a summary of what I want to do:

private static List ParseMessage(string message)
{
    //I need to check the message and see if there are any mentions at all.
    //If there are, I need to parse each mention, and check to see if the
    //parsed users exist.  If they do exist, I need to add them to the list
    //of users to be tagged to this message and return that list of users.
    return null;
}

Phase 2 – break it down into short, concise “verbs”:

private static List ParseMessage(string message)
{
   //parse the string, get each "@..."

    //check to see if any parsed users exist

    //if they do, then check to see if they are valid users

    //if user found, verify the user is an existing user

    //if user exists then add them to the list of users

    //finally return the list of users

    return null;
}

Phase 3 – Fill in the code

private static List ParseMessage(string message)
{
  List userList = new List<RegisteredUser>();
  List errors = new List();

  //parse the string, get each "@..."
  string[] splitStrings = message.Split('@');

  //check to see if any parsed users exist
  if (splitStrings.Length > 1)
  {
    foreach (string s in splitStrings)
    {
      //if they do, then check to see if they are valid users
      Match match = Regex.Match(s, @"A([A-Za-z0-9]+)", RegexOptions.IgnoreCase);

      if (match.Success)
      {
        //if user found, verify the user is an existing user
        string parsedUsername = match.Groups[1].Value;

        RegisteredUser user = DALUser.GetUser(parsedUsername, ref errors);
        if ( user != null)
        {
          //if user exists then add them to the list of users
          userList.Add(user);
        }
      }

    }
  }

  //return the list of users
  return userList;
}

Just remember, when you press the build button or type in make, all sorts of magical things happen. The comping process removes all the comments, fills macros, inlines inline functions, and links everything into one wonderful computer-readable program. Before all of that, computer programmers need to focus on everything occurring before that build button gets pressed, and that is writing human readable code.

Here’s a great discussion on writing and commenting good code.

On Your Mark, Get Set…

So I’ve come to a strange point in my life where, maybe for the first and only time, I can be employed but can also openly say that I’m thinking of looking for a full time job away from the one that I’m at now.  I have put a lot of thought into this.  I have asked around to close friends, coworkers, mentors, and have even posted the question to the programmers.stackexchange.com website on whether or not I should stay with the company I have interned at for the past 3 years.  I have heard differing advice from as many people as I have asked.  A few say I should stay, a few say I should go, but all agree I should at least interview for other jobs if only just to keep my options open.

My name is Brian Esserlieu, a Computer Science undergraduate at the University of California, San Diego.  I am doing exceptionally well academically (with a 3.9 GPA), and professionally I have had internships in the mobile application, web and pc application areas since 2007.  After deciding to interview for other potential positions, I realized I would like to start a blog, if not only to collect all of my ideas and experiences with interviewing preparations, but also to try to share as much of it as I can with anyone who may be starting out fresh in the programming world.

I have never really had a personal blog to capture my own interests (besides the one I worked on for 9 weeks last winter for a digital communications class), but I hope it will be as interesting to read as it will be fun to write.