Wednesday, January 16, 2013

Tri-Replicator - free app on google app engine

I am lazy and try to avoid doing things that I do not *absolutely* have to do. I guess this is not unlike most people. Especially I do not like doing the same thing twice when I know it could be done once. Where am I going with this you ask?

USA Triathlon runs a winter competition for athletes, but this one is unusual. It is all done via Internet and people compete by entering the amount of swim, bike and run miles they did in training. This is quite funny because in a real race it does not matter how far you ran over the past year, or how much you biked and swam. All that matters is your performance on a race day. This USAT competition is called USAT National Challenge Competition (NCC). The goal is to motivate folks to maintain active lifestyle over cold months of winter. People must enter their training miles into the USA website and can see where they are relative to other athletes.

The problem is that most athletes already enter their miles into the special sites, and the most popular one is In fact, I do not even enter my miles manually. I just upload  my workouts right from the Garmin GPS Watch and it automatically adds them to the training log on the trainingpeaks website.

The idea of entering my training miles by hand into yet another website was not very appealing, so I decided to write a program that would automatically copy my data from one website to another. Sounds familiar? Yes, this is what I do for work. I sell IBM WebSphere integration software. The problem I faced with this NCC for the winter could be solved by integrating two websites.

I decided to create a program that would automatically take my data from one site to another. After some further consideration I decided other folks would like to use that too. After all, there are 4,000 plus people participating in this NCC this winter. I am guessing about half of those folks are using trainingpeaks. Assuming 4 minutes per person per day entering data manually into USAT site, times 2,000 people, times 3 months, times 30 days, divided by 60 minutes in 1 hour: 4*2,000*3*30/60=12,000 hours.  WOW. If I made this application available on Dec 1, I could have saved 12,000 hours of triathlete's time (about 6 hours per person for entire winter). This is definitely worth a try!

Here is the final version up and running on the google app engine:

Where to run it?

Since the application had to be available for anyone to use, I needed a runtime environment outside of my home network. After looking around, I decided to use Google App Engine as it offers up to 5 million requests per month for free, supports Java runtime, offers nice Eclipse plugin, etc. Hosting cost would be $0. Nice.

As I was learning specifics of Google App Engine, GWT, etc. I found EXTREMELY useful free online resource - check it out. There are many great tutorials - very well written, all work and get you started very quickly.

How to access sites? has a well defined API. In fact they offer full WSDL with SOAP-HTTP and also simple XML over HTTP API. I used Jersey REST and JAXB to access and parse data from the trainingpeaks site.

USAT NCC site does not have any API and is only available via their old-looking HTML interface. After googling around I decided to use open source HtmlUnit library. It made it quite easy to parse HTML from USAT site and convert it into my own Java Plain Java Objects (POJOs).

Where and how to store data?

I needed to keep user accounts, passwords and a history of workouts that have already been replicated. For that I decided to use google database which offers JPA API and is well supported. I also used Java Cryptography Extension (JCE) to encrypt user data stored in the database, and encoding that data as Base64. I had to use secret key for encryption as building PKI or other advanced security measures seemed like a lot of work. This security part was perhaps the most time consuming part of the development process. Not to mention that USAT NCC site does not even support HTTPS, so all passwords flow in clear over HTTP anyway... At least I made all access to my application forced via HTTPS.

What user interface?

For the UI I decided to use Google Web Toolkit. It comes with excellent Eclipse support, is very easy to use and quite powerful. Not having used it before, I was surprised how easy it was to learn and implement. Perhaps in the future I build an Android native UI, just for kicks.

Going social

For promoting the app, I have added Java Script from the,  - now it shows floating social sharing buttons on the page.

Making money?

Just for the heck of it, I also added "Donate" button from PayPal in the "About" part of the app. I wonder if anyone bothers to use it? My wife bet that not a single person will contribute. I said at least one will. We shall see who wins this bet :-). This was not made to make money anyway, but I always wondered how those buttons worked as I have never used one before. Took me about 5 min to add the button to the app. This was probably the easiest part of the whole project.

Does it work?

I posted the link to the app on Facebook and a couple of forums yesterday, hoping that people will jump at the opportunity to avoid manual typing of data. It has been 24 hours and not a single person started to use the app, except for me. Hmm... I wonder if all that logic about saving 12,000 hours of people's time was flawed? ...

This USAT NCC competition runs every year, so the app can be used for many years to come. If it worked for 10 years, it can save 120,000 hours. If it worked for 100 years.......... Oh, wait, Google App Engine may not be around for that long :-), or perhaps USAT folks will bother to add this feature to their website.

What's next? Open Source it!

I suspect my assumption about half of athletes using to log their workouts is not entirely correct and there are many more different sites where people keep their training logs. It seems that Garmin Connect is quite popular as well. I can't build connectors to all those 3rd party websites that I am not using myself, but I architected the app in a way that it is trivial to add new connectors via generic interface I called TrainingAPI with methods like
  • void setupTrainingLog(String username, String password) throws TrainingLogException;
  • boolean login(...) throws TrainingLogException;
  • List<WorkoutSession> getWorkoutsBetweenDates(Date startDate, Date endDate) throws TrainingLogException;
  • List<WorkoutSession> addWorkouts(List<WorkoutSession> listOfSessions) throws TrainingLogException;
I think the next step is to open source the app and have other people contribute connectors, so that replication can happen between any and all systems. Say even between Garmin Connect and An ESB for traininglogs, huh?

If you are interested to become a contributor to this project, add new features, connectors to other online training log systems, etc. - please let me know! 

You can find the source for the project here: Feel free to make changes to the code and contribute back to the project!

1 comment:

  1. I suspect the lack of response might be mostly due to people being unaware of this service. - I'm sure there are many others like myself who would love to use this but are unaware of its existence. I only found out about it this morning on Garmin Forums at You really should try to get the word out! I recommend writing a press release and mailing/emailing it to a few magazines which cover the running sports (road running, triathlon, whatever). Thanks again for doing all this work!