Absolutely no idea

A blog by Lukas

The Ajax TODO list for your blog

February 19th, 2008 by lukas

Something I wanted to share today is a little widget on my blog that helps me keep this site up to date and improving. But first a bit of background.

This blog is not my first attempt at downloading the contents of my brain on line. Many years ago - before the time of blogs - I decided to create a web site. It never expanded past the first “under construction” page. A few years later I setup a wiki as a reference for various pieces of semi-useful technical info and that went well but it was private and lacked the reader feedback loop that a blog provides. So last year I started again. I wrote my first post in May 2007 but it hasn’t been until late last year when I picked up the tempo - with regular posts and small site improvements.

Something that has helped me a lot is the “AJAX ToDo List”. Not only is it cool but having a TODO list visible on the front page of the blog allows me to keep track of items that need doing, of posts that need writing and generally helps me stay focused and prioritise.

Here is a screenshot of the Ajax TODO list for my blog in action:

blog ajax todo list

Most important:

  • Easy and quick to maintain items - if it was too difficult to use I wouldn’t use it. This is where it’s Ajax capabilities came in - letting you to add and delete items with a single mouse click without page reloads.
  • Integrates into look and feel of blog - it’s small and easily integrates into general site layout - on the main page
  • Kept private - like any other functionality on the site it is easy to make it private by looking at whether the user is logged in and determining who it is.

I modified it slightly - added the add.gif icon and ensured it worked with my Wordpress blog. I have also added a check to display it only for myself (the admin user). You can download all files (including icons) with my modifications and details on how to use it from this link.

To get it going you need to do the following:

  1. Change database, user name and password in todolist.php to the ones for your wordpress mysql database.
  2. Make sure the references to the icons and todolist.php (in req.open() calls) point to the files in the correct location. This seems to be the main problem that most of the users have - for wordpress the location is something like “wp-content/themes/yourtheme/todolist.php”.
  3. In the calling code I have added a check to make sure it only gets displayed when the user is the admin user:
    <!-- only display the todo list if the logged in user is admin -->
    <?php global $userdata;
    if ($userdata->user_login=='admin') { ?>
     
      <h1>My TODO list:</h1>
      <div>
          <ol class="notelist" id="list">
          </ol>
      </div>
      <span class="info">help: !<i>italic</i>! *<strong>bold</strong>*</span><br />
     
      <script type="text/javascript" src="<?php bloginfo('stylesheet_directory'); ?>/todolist.js"></script>
      <script type="text/javascript" src="<?php bloginfo('stylesheet_directory'); ?>/todolist.php?init=1"></script>  
     
    <?php } ?>

Note: The todolist.php is called as javascript - this just means that the output of the todolist.php is considered javascript i.e. must evaluate as html when finished. This is important for debugging purposes as you cannot use the php print() command but must use document.write() to display any debug info.

My current TODO list contains 19 items and I am certain I will get most of them done this month!

Use the comments below to let me know whether you want to know anything else about this or my Ajax TODO list or suggest any improvements!

Posted in blogging | 2 Comments »

Use XAMPP to speed up your blog development cycle

February 16th, 2008 by lukas

One of the most important things when developing software is having a fast code-deploy-test cycle. To be a great software developer you not only have to be smart you have to work smart and speeding up this phase is key. A combination of a good integrated IDE (I always use the latest version of Eclipse), quick deployment capabilities for your server - possibly integrated into the IDE, a strong focus on unit testing and a LOCAL development environment all combine to provide a quick turnaround of this often very time-consuming phase.

On my latest engagement I was quite shocked to see some developers working in the Java Eclipse IDE but not understanding build-paths or project settings so they would edit the code in the IDE but build the application from the command line using maven. Then deploy the ear file on a remote Weblogic server and have to ssh to it to look at logs etc. while testing remotely (!!). Although it took me the better part of 2 days to install the software and get the complex development environment configured on my LOCAL machine, when it was done, I could code a change, deploy it on a locally installed Weblogic server and test it locally - all in under a couple of minutes. The time saved over the course of an entire project is well worth the initial couple of days outlay - not to mention the frustrations that you spare yourself when you deploy and test and realise you put that debug statement one line too far below and you have to repeat the whole cycle just to move it.

This also applies to the development of your blog and personal website. I have until now been using the Wordpress provided admin interface to edit files on this blog. This turned out to be painful so I downloaded the entire blog code to my computer and whenever I had to make a bigger change I would edit the files locally (I use the free PSPad) and upload them to the server to see whether the changes worked. This was still slow going - especially if you are making lots of tweaks and also - like myself - are still learning both php and javascript.

I found XAMPP. Apache, PHP, MySQL all in one, easy to install package.

  1. Download the appropriate XAMPP version from the site above.
  2. Install on local machine as per instructions. (e.g. in C:\xampp)
  3. If you have an existing MySQL server it will be used instead of the one that comes with XAMPP - make sure you change to your database login details in C:\xampp\htdocs\xampp\mysql.php
  4. Start Apache and MySQL from the supplied XAMPP Control Panel.
  5. Copy your entire blog/website (e.g. blogsite) directory files to C:\xampp\htdocs\blogsite
  6. Run your website by going to http://localhost/blog/blogsite
  7. If running Wordpress it will prompt you to recreate the tables when running for the first time.
  8. You will need to log in to the admin console to change to your theme - since the configuration of this is also stored in the database.

That’s it. You will now have your entire blog on your local machine. (NOTE: your blog posts etc. will of course not be migrated since you’d have to download the entire db schema and data and upload it into your local database)

You can do any development and testing locally - which will give you a much faster development turnaround time. Once done, go live by uploading all changes to server. You’re on your way to iterative development and eXtreme programming :)

Posted in software development career, blogging, programming | No Comments »

Job interview for Software Architect Role

February 14th, 2008 by lukas

I went for a job interview today for a Software Architect position. It was at a product company and they were looking for a Solutions Architect rather than an Enterprise Architect (many places don’t distinguish between the two). It appealed to me since I have been involved in a number of projects which I had to take through their entire life-cycle - from requirements gathering, architecture, design and development right through to testing and deployment. I am therefore more familiar designing architecture for smaller components (vertical architecture) rather than enterprise-wide solution architecture.

For reference, this is a quick summary of what questions I was asked - specifically relating to the Architect Role. (Note: although this company used Java/J2EE the questions were fairly technology agnostic)

  1. Based on one of your last projects explain what your approach was and the processes you used in the architecture phase.
    (e.g. describing steps in creating the Software Architecture Document (SAD), deliverables of this stage of the SDLC etc.)
  2. List some examples of OO patterns and describe when they would be used.
  3. Take a pattern (in this case the Adapter Pattern) and draw up a class diagram of how a client class might use such an adapter.
  4. Differentiate between the following relationship semantics in a class diagram and what they mean to object life-cycle:
    Hint: association, aggregation, composition. See this JavaRanch explanation.

    Class relationships

  5. Is the following a logical or physical data model and why:

    Many to many relationship

  6. On use cases - what does a use case represent. Explain the various symbols in a use case diagram. What are the main 2 use-case relationships and what do they mean in a systems context.
  7. Given an application (This pertained to their application - I was given an overview of components and functionality) what are the areas of potential performance bottlenecks and what are some of the ways these could be addressed?
  8. Explain the various transaction levels for declarative transaction handling. Draw up 2 different rollback scenarios and explain when a rollback could occur (i.e. on what type of exceptions).
  9. What do you see the role of an architect to be?
  10. How does an architect work with BA’s or the customer? What should the architect’s responsibilities be with regards to the development team?

I think this is about it. There were also a bunch of standard interview questions such as “Where do you see yourself in the next 2 and 5 years” etc. I’m not going to list these since they are pretty generic across all roles.

These were quite typical architectural level questions - high level without going to much into technical details - focusing mainly on the ability to model and represent business problems.

Has anybody experienced any other common (or not) questions asked at an interview for a Software Architect role?

Posted in software development career | 1 Comment »

Calling a secure Axis web service via SSL, through a proxy

February 5th, 2008 by lukas

In a recent project one of the requirements was to implement an Axis client for a web service with the following additional configuration:

  1. Web service traffic must go through a proxy
  2. Basic authentication turned on - login & password required
  3. Communication is over HTTPS with a self-signed SSL certificate

Although not overly difficult for somebody experienced in creating Apache Axis clients the implementation for the above is not trivial. This is mainly due to SSL’s complexity but also because the configurations to get the above working are required in slightly different places of the Axis client framework.

I hope the below may help someone through some of the steps required.

1. Routing web service calls through a proxy

We need to take care of this one first. If there is a proxy between the client and the server and the client doesn’t know to route the traffic through it the requests won’t even reach the server and will just time out. (If your web browser uses a proxy then your local web service will as well since we are using SOAP over HTTP. You can most likely use the same proxy for the settings for the web service).
Without a proxy configured the connection just times out:

AxisFault
 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
 faultSubcode: 
 faultString: java.net.ConnectException: Connection timed out: connect
 faultActor: 
 faultNode: 
 faultDetail: 
	{http://xml.apache.org/axis/}stackTrace:java.net.ConnectException: Connection timed out: connect
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
        ...

Telling Axis to use a proxy is easy. We use Axis properties to set both the proxy host and the port:

private void configureProxy() 
{
    //this setting (from a config file) controls whether the proxy is to be used or not
    if (ApplicationProperties.useProxy()) 
    {
	AxisProperties.setProperty("https.proxyHost", "192.168.15.1");
	AxisProperties.setProperty("https.proxyPort", "8080");
    }
}

2. Basic Authentication

Once Axis knows to use a proxy we can actually reach the server. But calling a web service that requires HTTP basic-auth without the proper credentials will fail. Basic authentication includes a base64 encoded login and password set in the http header of the message. Without these details in the header we will get an error similar to this:

AxisFault
 faultCode: {http://xml.apache.org/axis/}HTTP
 faultSubcode: 
 faultString: (401)Authorization Required
 faultActor: 
 faultNode: 
 faultDetail: 
	{}:return code:  401
&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML 2.0//EN&quot;&gt;
&lt;HTML&gt;&lt;HEAD&gt;
&lt;TITLE&gt;401 Authorization Required&lt;/TITLE&gt;
&lt;/HEAD&gt;&lt;BODY&gt;
&lt;H1&gt;Authorization Required&lt;/H1&gt;
This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.&lt;P&gt;
&lt;/BODY&gt;&lt;/HTML&gt;
 
	{http://xml.apache.org/axis/}HttpErrorCode:401
 
(401)Authorization Required
	at org.apache.axis.transport.http.HTTPSender.readFromSocket(HTTPSender.java:744)
	at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:144)
        ...

Taking care of this is also quite easy as the generated Axis client stub (if you’re using a standard JAX-RPC web service) provides methods to set the user login and password for basic authentication. (Naturally, you need to know what these are to be able to connect)

private void configureBasicAuth() throws ServiceException
{
    //the port is the interface for the web service
    this.configuredPort = ((MyWebServiceLocator)getService()).getMyWebServicePort();
 
    MyWebServiceBindingStub myStub = (MyWebServiceBindingStub)configuredPort;
    myStub.setUsername("userName");
    myStub.setPassword("password");
}

3. Communicating over HTTPS with a self-signed SSL certificate

Now that we’re authenticated our web service request makes it through but the SSL connection cannot be established since we’re not providing the correct certificate. In my instance the server requires an unsigned (or self-signed) SSL certificate.

If we don’t provide one the request will bounce with the following error:

AxisFault
 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
 faultSubcode: 
 faultString: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
 faultActor: 
 faultNode: 
 faultDetail: 
	{http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
	at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
        ...

Implementing SSL using certificates is a bit more tricky. It requires creating a custom SSLSocketFactory which uses the correct SSL certificate and setting this factory as the one to be used by Axis. The certificate is packaged into a custom keystore which is packaged and released with the client application. The steps required to implement this are:

  1. obtain the certificate to be used on the client-side
  2. create a custom keystore to store the above certificate
  3. create code for the custom ssl socket factory by extending org.apache.axis.components.net.JSSESocketFactory (reads the custom keystore)
  4. configure the new custom factory to be used by Axis

To create the custom factory we first need to create a custom keystore which will hold our self-signed certificate. The “Using Self-Signed Certificates for Web Service Security” article explains nicely how this is done.

(The certificate you receive could be a .crt. The keytool utility may throw a tantrum at this as it expects a .cer file. To convert to this Base-64 encoded X.509 certificate, double-click your original .crt file -> Details -> Copy to File and follow the prompts. Save the resulting certificate as a file with a .cer extension and keytool should now be happy)

I used the following command to create my CustomKeystore.jks:

keytool –import –noprompt –trustcacerts –alias CustomKeystoreAlias –file CERTIFICATE.cer –keystore CustomKeystore.jks –storepass customKeystorePassword

(NOTE: for some reason I could not copy the command into the CommandPrompt window and had to type it out)

Once the keystore is created, we include it in the client application - somewhere on the classpath. The next step is to code the custom SSLSocketFactory:

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Hashtable;
 
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
 
import org.apache.axis.components.net.JSSESocketFactory;
import org.apache.axis.components.net.SecureSocketFactory;
import org.apache.commons.lang.StringUtils;
 
 /**
  * Custom SSL socket factory to use our integrated keystore.
  *
  * Based loosely on org.apache.axis.components.net.SunJSSESocketFactory
  */
 public class MyCustomSSLSocketFactory extends JSSESocketFactory implements SecureSocketFactory {
 
     /* local keystore password */
     private static String MY_KEYSTORE_PASSWORD = "customKeystorePassword";
 
     /* local keystore file (contains the self-signed certificate from the server */
     private  static String RESOURCE_PATH_TO_KEYSTORE = "CustomKeystore.jks";
 
     /**
      * Constructor MyCustomSSLSocketFactory
      *
      * @param attributes
      */
     public MyCustomSSLSocketFactory(Hashtable attributes) {
         super(attributes);
     }
 
     /**
      * Read the keystore, init the SSL socket factory
      *
      * This overrides the parent class to provide our SocketFactory implementation.
      * @throws IOException
      */
     protected void initFactory() throws IOException {
 
         try {
             SSLContext context = getContext();
             sslFactory = context.getSocketFactory();
         } catch (Exception e) {
             if (e instanceof IOException) {
                 throw (IOException) e;
             }
             throw new IOException(e.getMessage());
         }
     }
 
     /**
      * Gets a custom SSL Context. 
      * This is the main working of this class. The following are the steps that make up our
      * custom configuration:
      * 
      * 1. Open our keystore file using the password provided
      * 2. Create a KeyManagerFactory and TrustManagerFactory using this file
      * 3. Initialise a SSLContext using these factories
      *
      * @return SSLContext
      * @throws WebServiceClientConfigException 
      * @throws Exception
      */
     protected SSLContext getContext() throws WebServiceClientConfigException {
 
        char[] keystorepass = MY_KEYSTORE_PASSWORD.toCharArray();
 
	if (StringUtils.isBlank(new String(keystorepass)))
		throw new WebServiceClientConfigException("Could not read password for configured keystore!");
 
	InputStream keystoreFile = this.getClass().getResourceAsStream(RESOURCE_PATH_TO_KEYSTORE);
 
	if (keystoreFile == null)
		throw new WebServiceClientConfigException("Could not read the configured keystore file at "+RESOURCE_PATH_TO_KEYSTORE);
 
	try 
	{
		// create required keystores and their corresponding manager objects
		KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
 
		keyStore.load(keystoreFile, keystorepass);
 
		KeyManagerFactory kmf = 
			KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		kmf.init(keyStore, keystorepass);
 
		TrustManagerFactory tmf = 
			TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		tmf.init(keyStore);
 
		// congifure a local SSLContext to use created keystores 
		SSLContext sslContext = SSLContext.getInstance("SSL");
		sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
 
		return sslContext;
	} 
	catch (Exception e)
	{
		throw new WebServiceClientConfigException("Error creating context for SSLSocket!", e);
	}
    }
}

The last step required is to tell Axis to use the above MyCustomSSLSocketFactory as the default ssl socket factory. This is again achieved by setting AxisProperties:

private void configureSSL() 
{
    //this is configurable so that it can be switched off in development mode
    if (Configuration.useSSL())
    {
	//use our custom SSLSocketFactory 
        AxisProperties.setProperty("axis.socketSecureFactory","com.company.application.util.MyCustomSSLSocketFactory");
    } 
    else 
    {
	// The fake factory must not be used in production environment because it ignores any certificates but  
	// it is convenient to have for testing purposes.
	AxisProperties.setProperty("axis.socketSecureFactory","org.apache.axis.components.net.SunFakeTrustSocketFactory");
	log.debug("WARNING: SSL CERTIFICATE CONFIGURATION IS TURNED OFF!");
    }
}

In the code above we have the option of either using our new fully configured MyCustomSSLSocketFactory or the provided SunFakeTrustSocketFactory. The latter is very useful for testing and will accept any ssl certificate. It is mentioned on the Axis wiki here.

This should be it. Communication should now flow freely between client and server in a reasonably secure manner.
Feel free to post comments.

Posted in programming | 22 Comments »

Hang on to your Krugerrands and gold bars

February 1st, 2008 by lukas

Having spent some years living in South Africa I try to keep up to date with what is on the go in that beautiful country. I am quite disappointed though to see what is happening there politically and worried about Jacob Zuma becoming president in the near future…

But the latest set of news about the power crisis is quite stunning although probably not surprising. With South Africa being the largest producer (closely followed by China) of gold in the world this is going to have quite an impact on the price of the shiny stuff as Mines are shut as Eskom, the state-owned electricity provider, tries to ration out the power to those most in need. Gold production falls, prices will rise.

Krugerrand

Today it is US $924.05 / ounce. I wonder whether it will reach US$1000. I wonder whether gold stocks will go up as well.. And what did I do with my stash of Krugerrands?

Posted in Uncategorized | No Comments »