Charles' Blog

General ramblings of a tech geek.

The Galago Arrives…

| Comments

Today, when I got home, the first thing greeting me was the box containing my new Galago Pro. Very exciting. I’ve just started at Meducation so I needed to get a new development machine. The Galago is from System 76, a Linux-only laptop supplier that ship machines pre-configured with Ubuntu.

Actually, I was a bit apprehensive about the purchase. In terms of spec, and money, the machine is awesome. However, the keyboard has attracted a significant amount of criticism on Internet forums (see here and here). I didn’t know if I would find the keyboard annoying or whether it would be fine. I’m not a particularly demanding user, I spend the majority of my time in the console and I don’t have a particular need for typing at a high RPM. In fact, this blog post is the longest continuous bit of typing I’ve had to do this week.

So, the keyboard? Well it’s not too bad. It’s got chicklet style keys, and probably doesn’t have an experience anything like a MacBook Pro (which, incidently I also find I miss keys on). At first, it seemed that certain key strokes didn’t register. For me, the key missses tended to be alpha keys near the edge of the keyboard (A, S, M etc). I don’t think there’s anything technicaly wrong with the keyboard, it’s probably because my fingers strike those keys with less force. To be honest, I tend to struggle with most new keyboards I try, it’s one of the things I find difficult about frequent pair rotation. In fact, when I think about my old favorite machines, they all had sigificant burn in. I still harken after my old Sony Vaio, I wrote my PhD thesis on that, and I adore my little Asus netbook with it’s diddy Atom processor and I wrote my book on that. However, with no immediate writing projects on the horizon, the Galago keyboard will not have to endure all that hammering. Maybe I should blog more? If I can get through this post without falling out of love with the laptop, then I’ll probably be ok going forward.

Right. So that’s the keyboard issue discussed – with a final judgement due later. Now to describe the rest of the machine. The Galago is, I think, the best looking laptop I’ve ever bought. It’s sleek and solid, and even with the extra hard disk I fitted, it’s pretty light. The screen has full HD resolution and is bright and sharp. The rear cooling grills also seem to work very well – no overheating so far. One or two reviews I read before buying the device expressed concern that the rather narrow hinge between the screen and the keyboard was rather narrow, it doesn’t feel overly fragile, but I am pretty rough with my kit so time will tell there too.

Initially I thought that buying a System76 was a bit gimmicky. The machine itself is actually manufactured in France, and I’m in the UK, so I could have got the same box from a European supplier. Even with shipping, System76 was actually marginally cheaper, but I have to admit that deep down I wanted that Ubuntu key. Yeh I know, it seems petty, but I’ve been using Ubuntu for about 7 years, and before that I was a RedHat and Solaris guy. So it’s been 13 years since I last used Windows as my main system and that makes me wondern why I must have that Windows key? Stickers are all well and good, but finally I have the proper solution.

The other thing that’s amazing is the way the hardware just works. I powered on (very quickly, thanks to the SSD) and went straight into the final configuration screens of the Ubuntu setup process. No need to download and configure an ISO – the System76 guys had sorted it. For the first time ever, I was able to go from unwrapping a UPS parcel to typing in a shell within minutes.

It’s also fantastic that I can use and rely on all those ‘function’ keys that I’m usually scared of. During installation I playfully hit func+F4 thinking ‘I wonder what this key with the Moon symbol does’. Immediately, the laptop suspended to disk and switched off. I confess that I was mildly concerned, thinking I’d suspended mid installation and would be forced to rebuild from scratch. Far from the disaster I anticipated, the laptop resumed in exactly the same state. I know it’s probably not that awesome to all you Mac and Windows users, but I’m sold.

All in all, it’s a fab machine, that I think I’ll enjoy using. And the keyboard? Well, since I haven’t missed any keys in the last few paragraphs. I think we’ll get along just fine.

Bye-bye Black Pepper, Hello Meducation

| Comments

Anyone watching my Twitter and Github profiles over the last couple of weeks will have noticed that I’m about to embark on a new challenge. I’ve decided to move on from Black Pepper Software and join the expanding team building Meducation.

Meducation are a really exciting Birmingham based start-up. They provide a social network targeted at medics that has a strong educational focus. Founded a few years ago, they have been steadily growing, and have just raised funding to expand and accelerate. I’m going to be joining a fantastic team who are passionate about developing a successful business with a great set of values.

Despite all the excitement, moving on is not without a bit of sadness. Black Pepper is a fantastic company with a fantastic culture and jam-packed with highly intelligent people. I will miss them, and wish them every success in their future work.

Custom Reverse Proxying With Node.js

| Comments

On a number of occassions over the last year or so, I’ve found myself writing wanting to create a reverse proxy to front a number of HTTP services. For me, the usual requirement is that I want to access these services via AJAX requests, and using a reverse proxy allows me to not need to worry about cross-site scripting (XSS) or configuring cross-origin resource sharing (CORS). Node.js is a fantastic tool for doing this. Particularly if you lean on the well-regarded node-http-proxy module.

If all you need is static proxying/routing, then node-http-proxy project supports a variety of However, I usually find myself turning to this library when I want to do custom routing. So in this post, I focus on configuring the proxy with custom code.

In this blog post, I’ll share some code snippets to create a simple reverse proxy in Node.js and then move onto a slightly more complicated example with some routing and express middleware. Finally, I’ll show how to base the routing on an asynchronous call to another service (e.g. a service-discovery service for looking up endpoints ).

PDF Templating With DocXReport

| Comments

This post was originally written for the Black Pepper Software blog. The original was posted on 12/09/2013.

It is very common requirement for software systems to generate a PDF document of some kind. For instance, at Black Pepper, we’ve built a number of e-commerce systems, and usually our clients have a requirement to produce a nicely formatted invoice or contract which their customers can access through the web.

We often work on a Java stack, and there are therefore a number of approaches to generating a PDF, including Apache FOP (based on XSL), iText, and a variety of others [1]. In a number of solutions we’ve gone down the iText approach since it’s pure Java and therefore reasonably straight forward to integrate and test. However, it presents a DOM-based approach which is not without it shortcomings. A better solution is to use a template so that layout can be separated from the PDF generation. That’s precisely what we wanted to do for a recent project, when we discovered the XDocReport library [2] which provided exactly what we needed. This post describes how to get started with that library.

Creating a Simple AMF Client for Testing

| Comments

This post was originally written for the Black Pepper Software blog. The original was posted on 30/04/2013.

A few months back I had to debug an Adobe Flex application that used Adobe Message Format (AMF) for client-server communication. For readers unfamiliar with Adobe’s Flex/Flash stack, AMF is a binary RPC communication protocol, usually powered by Adobe’s BlazeDS technology. The application I was working on used BlazeDS to expose a number of AMF web services, backed by a fairly standard Java/Spring/Hibernate stack.

As I started investigating the bug, I quickly began to suspect that the root cause was data related. Since many of the application screens were data-driven, I conjectured that there was inconsistent or incomplete data being returned from the web services. At the time, I didn’t have access to a stable version of Adobe FlexBuilder for Linux, so I wasn’t able to easily jump in and attach a debugger to the Flex application. However, I was able to read the code and understand a bit about the RPC service calls it was making. The server-side access logs also provided a good idea of the client-server interactions that were happening. In order to gain further insight into the scenario under test, I found myself wanting to ‘see’ the data that was flowing between the two applications.

Correlating Log Entries Using Log4J and the Mapped Diagnostic Context

| Comments

This post was originally written for the Black Pepper Software blog. The original was posted on 20/12/2012.

Over the last couple of years, it has become increasingly common for web applications to be built using client-side frameworks that interact with a remote server via asynchronous requests. Unlike a traditional app, that makes a single request per page, a modern web application will probably make many asynchronous HTTP requests. This poses a challenge when analysing server logs, since it can be difficult to identify which requests belong to the same client.

In this blog post I’ll describe a simple technique we’ve applied to retro-fit a client-aware correlation token to the server logs of an existing web application.

Playing With Java Timestamps

| Comments

The shortcomings of Java’s native date and time support is well known. Asking a developer about a date/time problem in Java is a good way of judging their exposure to building systems with it. For new projects, Joda time is excellent, but there’s plenty of native code out there that uses the standard Java APIs. Today I ran into an interesting and unexpected behaviour relating to Timestamps.