I'm sat waiting for Microsoft Visual Web Developer 2008 to download so I can do some decent, hopefully, debugging in MSIE, so it's blog time...
I was going to wait until April 2nd to post this, but due to MS VWD taking an age to install and me being really exhausted (can't stay up after midnight as I'm just too tired) I thought I'd post now. This is probably going to be a ramble, but what the heck...
Licensing
I'm coming to loathe the licensing module in our plugins. It's something we needed to do for a long time, but man alive, has it been painful!
Since Theme Builder was first launched, way back in the 4th month of Adaptavist, we've gone from paper invoicing and using MS Word documents, to having the online PayPal cart and a custom built invoicing system for accepting payments via practically every possible method from around the world.
The net result is that we have hundreds (if not thousands, I lose track) of customers that purchased Theme Builder before we put the licensing module in. We've had to centralise all the accounts data - which resulted in us having to build a custom accounts system first and then write a new version of our internal control panel software, followed by literally weeks of wading through databases checking over details, just to get to the point where we can start properly creating license keys in a consistent manner.
We've run in to all kinds of problems along the way - in particular tying old bank transactions and old paper invoices together. In the early days, paper made sense - we only had a few customers, but within a few months of Theme Builder going on sale we had customers in 37 countries and if you read my blog you'll know what effect that had on all our internal systems - they crumbled under the logistics of rapid growth.
So, we started by getting a list of all the Theme Builder licenses from all the different sources in to one place. We then realised we needed a way to link the data to actual payments as well as the actual license details being sent out - this was no trivial task.
I don't know about elsewhere in the world, but here in the UK all the financial systems are firmly stuck in the dark ages. For example, we tried several of the leading accounts packages and none of them had a usable API and none could handle multiple currencies and PayPal.
So, we started developing an accounts package that would suit our needs. What started out as a 2 week project has so far taken over 2 months - the system is turning out far better than we imagined, but it's taken a heck of a long time.
We decided to use Ruby on Rails as a Java based system of that complexity wouldn't even be out of the design phase by now. It's amazing how quickly you can develop apps in RoR, the main time creep has come from us realising just how complex our accounts are.
We've had to build in lots of validation routines, reports and all kinds of other stuff that are all able to handle multiple transactions for multiple cost centers spread across multiple bank accounts and currencies, etc. Pain, lots of pain, but we're getting there.
So, with accounts system in place (well, it's still being worked on but the hard stuff is done) and a veritable herd of people working on the data in it on an ongoing basis, our attentions started to turn to the actual license key generation and the ability for the plugins to do the right thing based on the license key installed.
We decided that rather than issue free license keys (for personal, community, non-profit, developer, evaluation, etc) we'd just make the plugin run in free mode when it's installed on to a Confluence instance that has a free license of some type. That part was relatively easy.
We've had to spend a lot of time on the UI of the license details screen in the plugins (the licensing code is also in Community Bubbles which we've quietly released) to make sure that it's easy to read and understand. We're still making tweaks to that screen even now.
In the plugin we've had to deal with all kinds of license scenarios. For example, you can't upgrade to a version of the plugin that was released after your maintenance period expired. There are certain types of license that prevent use of the plugin after expiry (eg. an evaluation) and other types that continue to run after expiry (eg. commercial licenses). We're still fine-tuning that aspect of the plugin. Then there's the checking that the license in use is sufficient for the Confluence installation it's installed on.
Anyway, with all that done, we then come to the license key generation. We ran in to several nightmares with this aspect of the system...
Because accounts systems are generally designed for accountants and not the rest of the business, we had to find some way of linking payments to licenses that had been sent out. This initially involved putting our list of existing licenses in to a new database and then linking to the usernames on our website associated with the license keys. However, that's no easy task as many licenses were purchased before we moved our support and tracking over to JIRA - we used a product called Kayako eSupport but it utterly crumbled under load and was completely separate to the rest of our Crowd-linked architecture.
So... We've had to manually retrace all the license keys that were sent out and try and link them to payments and invoices, etc. Utter nightmare. If we'd known our company was going to be successful from the outset, we'd have done things very differently, but alas, we had no idea that we were going to grow so quickly.
We also ran in to issues with clustered licenses - for example, you could purchase an initial license key, then upgrade your Confluence install to a cluster thus require a new "node" license key, then add another node, etc. You end up with licenses and bits of licenses spread throughout the year making things utterly confusing, not to mention that Confluence has separate licenses for an Enterprise Node and an Unlimited Node which we'd originally mirrored in our licensing model. Due to the chaos this caused, we decided to simplify our clustered licensing and just have a single "Cluster" license that will work on any Confluence cluster regardless of number of nodes.
We were hoping to launch the new license generator yesterday, but then we ran in to yet more problems. We'd overlooked one small but vital aspect of the way things can be purchased - a single payment can be used to buy both a new Theme Builder license and also a Maintenance Extension for it - effectively making the maintenance period 24 months instead of 12.
This means that the system now has to not only keep track of how many months maintenance a license has, it also needs to be clever enough to work out when a single payment includes both the license and a maintenance extension :o
So, we've now got a custom-built accounts database, a custom built license database (used as a staging area) and have had to write a custom license key generator (we used AppFuse for this as it needed to be in Java and linked to Crowd for SSO). Hopefully by next Monday we'll be up an running with the new systems and things can start getting back to normal (and Dan, Paul, Emma and others can start doing something other than wading through databases all day).
If you're planning on adding licensing to your plugins, do it from the outset!
Debugging
To useful bits of info if you need to debug in Safari or MSIE:
We've grown!
I'm delighted to announce that Adaptavist has doubled in size of the past few weeks (literally). We've taken new staff on in support, development, accounts, documentation and design and will likely be taking more staff on later in the year if things pan out the way we expect them to.
The new recruits are already helping to ease some bottlenecks that had been causing trouble over the past few months. As a start-up we can't afford to take on the wrong people so we had to do a fair bit of hunting to find people who were "on the ball" and fit in to our company culture.
Anyway, VWD has finally finished installing so I'm off to do some debugging before midnight (which isn't so far away...)
I'd like to contest that Ruby on Rails deployments are far-and-away faster than Java agile deployments (especially those based on the AppFuse framework using Struts2 and with a good understanding of the libraries in play).
I would agree that RoR is easier to pick up and play with, has a lower barrier to adoption and is certainly the buzz word in the industry ... however when things go wrong, they go spectacularly wrong (bugs in both Ruby and RoR were found with our accounts project).
When it boils down to total time spent from start to finish on a project, I think if you have a good Ruby developer and a good Java developer who knows their stuff, you may as well toss a coin to predict who would come first.
(It's worth noting that the way in which Rails works is not that dissimilar to Struts2/WebWork2, JPA/Hibernate, Sitemesh et al)
It was much easier to make changes in the RoR system - from what I've seen the Java based stuff is harder to make ad-hoc changes to, especially once the data model and normalisation are implemented.
Not at all, you've not seen me develop with AppFuse – changes happen in real time unless you're changing logic where a reload take < 30 seconds.
Model changes are tough when you care about the data which is in there as you have to migrate between them. Be wary of anything that claims to have magic which resolves that without effort. Active Record and JPA share similar mitigation strategies, so neither is better.
Try using both and then decide, rather than making sweeping judgements from the sidelines