Posterous theme by Cory Watilo

CFDynamo: A CFC Wrapper for Amazon DynamoDB

Earlier this week I began implementing a DynamoDB solution for a client. DynamoDB is a NoSQL solution long ago planned but only recently released on Amazon Web Services. It is more closely related to Cassandra than MongoDB or CouchDB but offers some interesting and enticing features (e.g., all DynamoDB tables exist on SSDs, so the I/O is pretty damn fast!). 

My client's site is built with CFML and runs on Tomcat/Railo 3.3.1 (to be upgraded to 3.3.2 this weekend) on a load-balanced EC2 instance that employs several other AWS services, such as a MySQL DB on RDS, S3, CloudFront and the new ElastiCache. While our RDS database serves most of our needs, some of our data is quite complex and we feel we would better served breaking some items out into a NoSQL solution. 

After an initial review of NoSQL options, we thought we'd go with MongoDB but, with the announcement of DynamoDB, we decided that it would be a better choice for our team because all DynamoDB instances are managed by Amazon's experts ... and this seemed a might better option than building and managing our own MongoDB cluster!

As many/most CFML developers know, there is no CFML SDK for Amazon Web Services. And, if you want to write CFML code to directly access AWS services such as DynamoDB, it can be a pain in the ass, to say the least.

Why such a pain? Primarily because you have to manage your security credentials and session tokens yourself/in your CFML code and none of these actions are straight-forward or easy. Plus, it ends up pretty non-CFMLy because it requires a shit-ton of code (IMHO). The pre-built AWS SDKs, on the other hand, handle all these security actions for you. 

Fortunately, there is an AWS Java SDK, as I am sure you all know. And, thankfully, we CFML developers can (fairly) easily access and use Java APIs/libraries directly in our CFML code. Hooray!

So, to make my life easier, I created and started working on a project I named CFDynamo (yep, typically uninspired CFML project name :). To start, I have integrated the security aspect (i.e., enabling CFDynamo to access your DynamoDB instance) and table listings. To get started quicker, I created a couple of tables in the AWS console. 

If you are interested in the project, please check it out on Github. The README contains instructions for getting the Java SDK setup and running on either Tomcat/Railo or ACF 9. I won't bore you with more setup details here.

I'll be adding more API functions/calls to CFDynamo between today and Monday. Feel free to watch the Github repo for updates, which should come in the following order: 

  • createTable
  • deleteTable
  • updateTable
  • getItem
  • updateItem
  • query
  • scan
  • refine putItem

And, of course, please fork the project and make some better coding updates than I will and I can merge your pull requests!

CFWheels StatesAndCountries Plugin Updated

With many thanks due to Jordan Clark, my StatesAndCountries plugin for CFWheels has been updated.

Because my CFML work is focused solely on Railo and I do not have a current Adobe ColdFusion installation on my main work machine, I missed that there was an issue on ACF with the plugin (it could not find the asset files). 

Jordan tweaked the plugin to work for him on ACF and then I went back in and made a few tweaks so that it will work on both now. 

Thanks, again, to Jordan for his assistance and recommitting the code (pull requesting, whatever :) to the GitHub repo. This is why I freaking love open source code!

CFWheels and SES URLs

I’ve been talking with a fellow CF'er and he was having some trouble getting SES URLs rolling in a Tomcat and CFWheels application that he’s working on. Since I had to go through all sorts of ‘fun’ times with SES URLs and Wheels a year ago, I thought I’d write up a little post on my experiences and how I got the URLs I want. And, really, it ain’t that bad.

URLRewriteFilter

First things first, download the excellent Java Web Filter library, URLRewriteFilter. Once downloaded, expand the Zip Archive. You will see a WEB-INF folder, inside of which, are two important items: urlrewrite.xml and lib/urlrewrite-3.2.0.jar. From here, it’s not too difficult to figure out what’s next … move these items (the XML and JAR) into the corresponding locations in your application’s WEB-INF folder. Note that you may need to create a lib folder in your WEB-INF (I did).

WEB.XML

Next up, you need to add a declaration to your web.xml file (also located in WEB-INF) so that your server knows to load the URLRewriteFilter JAR. The addition is pretty simple.

Now the filter will be loaded when your server starts.

URLREWRITE.XML

Next, you need to instruct the URLRewriteFilter how to filter and pass on your requests, which is done by providing the conditions under which the filter should not run (in this case). For Wheels, there were two levels at which I did not want the filter to kick in:

  • when certain folders were requested
  • when specific files were requested

For organization and readability, I organized my filter declarations by folders and then files. As you can see from the XML document belowm I select all the major folders where your CFML server is doing stuff (e.g., flex2gateway or railo-context) or where static files are server (e.g., javascripts, stylesheets).

Once your conditions are in place, you need to just tell the filter from what and to which URLs should it rewrite. For Wheels, this appears as follows:

CFWheels

The last piece of the puzzle … the framework itself. There are two (easy) steps to making URL rewrites happen in Wheels:

  • Tell Wheels to turn on URLRewriting
  • Add a piece of code to events/onrequeststart.cfm for populating the path info**

The first step is super-duper easy. Just add the following line in your config/settings.cfm file:

set(URLRewriting="On")

The second step is also easy. Add the following to events/onrequeststart.cfm:

if(structKeyExists(url,"$pathinfo")){
    request.cgi.path_info = url.$pathinfo
}

**EDIT: Many thanks to Tony Petruzzi for pointing out this far more elegant solution.

That’s it. From here, restart your CFML server and you’re ready to roll. To see my SES URLs in action, head to Ouray Climbing and start clicking some links!

P.S. I did write this post rather quickly, so let me know if you spot any errors or have any issues trying the same thing.

Rails HAML Heads Up with CSRF Tag and Destroy Calls

Rails HAML Gotcha with CSRF

I’ve been doing a good bit of work with Ruby 1.9.2 and Rails 3.0 and 3.1 lately. It’s been a pretty exciting time as I have not really delved heavily into a new language in a couple of years (I had lots of CFML work from 2009-2011).

Right now, I’m working on a site for our volunteer fire department, of which I am a member. I’ve got the front-end of the site in place and lots of the admin/CMS section done, too. However, as I started running through admin/CMS tests, I found that none of my delete/destroy calls were not working. Every time I’d try to delete something, it would log me out, force me to log back in and then fail to have run the delete.

I researched the issue on the Interwebs but only found references to needing the cross site request forgery meta tag in place (csrf_meta_tag) in your documents. However, I did have this in place … see the code block below:

Admin Head Section

%head
    %title Website Administration
    %meta{ :http_equiv=>'Content-Type', :content => 'text/html;', 'charset' => 'utf-8' }    
    = stylesheet_link_tag "960","reset","text","red","smoothness/ui", "wysiwyg/jquery.wysiwyg", "lightbox", "admin"
    = javascript_include_tag "jquery.min","jquery-ui-1.8.7.custom.min.js","jquery.blend-min","wysiwyg/jquery.wysiwyg", "jquery.lightbox", "jquery.slideto.min", "jquery_ujs","admin"        
    /[if IE 6]
        = stylesheet_link_tag "iefix"
        = javascript_include_tag "pngfix"
        %script{:type=>"text/javascript", :language=>"javascript"} DD_belatedPNG.fix('#menu ul li a span span');
        = csrf_meta_tag

Notice anything screwy in that? Because I clearly did not. My csrf_meta_tag was indented one step too far so that it was included in the IE6 conditional comments. D'oh!

It should have been …

%head
    %title Website Administration
    %meta{ :http_equiv=>'Content-Type', :content => 'text/html;', 'charset' => 'utf-8' }    
    = stylesheet_link_tag "960","reset","text","red","smoothness/ui", "wysiwyg/jquery.wysiwyg", "lightbox", "admin"
    = javascript_include_tag "jquery.min","jquery-ui-1.8.7.custom.min.js","jquery.blend-min","wysiwyg/jquery.wysiwyg", "jquery.lightbox", "jquery.slideto.min", "jquery_ujs","admin"                                                                                                
    = csrf_meta_tag   
    /[if IE 6]
        = stylesheet_link_tag "iefix"
        = javascript_include_tag "pngfix"
        %script{:type=>"text/javascript", :language=>"javascript"} DD_belatedPNG.fix('#menu ul li a span span');

Or …

%head
    %title Website Administration
    %meta{ :http_equiv=>'Content-Type', :content => 'text/html;', 'charset' => 'utf-8' }    
    = stylesheet_link_tag "960","reset","text","red","smoothness/ui", "wysiwyg/jquery.wysiwyg", "lightbox", "admin"
    = javascript_include_tag "jquery.min","jquery-ui-1.8.7.custom.min.js","jquery.blend-min","wysiwyg/jquery.wysiwyg", "jquery.lightbox", "jquery.slideto.min", "jquery_ujs","admin"        
    /[if IE 6]
        = stylesheet_link_tag "iefix"
        = javascript_include_tag "pngfix"
        %script{:type=>"text/javascript", :language=>"javascript"} DD_belatedPNG.fix('#menu ul li a span span');
    = csrf_meta_tag

Long story short, be sure to check your HAML indentations and orders if something is not working as expected!

How I Got Started in ColdFusion

Steve Bryant recently suggested we make August 1, "How I Got Started in ColdFusion" day. The idea is to get as many CFML developers to write a blog post detailing how they got started with ColdFusion. I think it's a wonderful idea and, as such, following is my own story. 

My first forray into ColdFusion began late in the magical decade that brought us grunge, a revival of hippie/jam-band music, and a booming economy: the 90's. I had just finished my Masters degree in Anthropology at the University of California, Santa Barbara and was moving (back) to the Washington DC area to get married. After an extended honeymoon of several months backpacking in the US West and another several months in Europe, I needed a job. Surprisingly, an MA in Anthropology did not yield jobs outside of a McDonald's. Weird, I know. 

Shortly after I graduated from the University of Pittsburgh in 1992, I got a job at Quark, Inc. as a support technician. After a couple years at Quark, I was asked to and happily pitched in on the company's first-ever website. As a result of my QuarkXPress knowledge and experience, I was able to get a job in the marketing department for Government Executive magazine; designing and laying out brochures, simple HTML websites/web pages for events, mailers and the like.

After a month on the job, my boss requested that I build a website for an upcoming conference our magazine. The company's online magazine was built with ColdFusion 4.0 and we decided that it would be best for me to go ahead and use ColdFusion to build my marketing site. So, I set off one day after work with the following book under my arm: 

51echyjxyrl

I spent a week, and this is what I LOVE about CFML, working through the book and some examples. One week later, we had a database-driven website for our upcoming Excellence in Government 2001 Conference. I just think this is the amazing thing about CFML ... I knew some HTML and some JavaScript and before I knew it, I had a nice looking, fully functional database-driven website to promote and provide all the required details about our upcoming conference. From a total novice to a solid, well working (albeit not a complex) site in two weeks ... that is just awesome! 

Okay, fine ... get picky ... I was using Access and maybe calling that a database-driven site is giving it a bit too much credit :). I kid. I kid. 

The site was a huge success and before I knew it my job had morphed from a marketing person to, basically, a web developer creating ColdFusion-driven websites for every thing and anything our directors could think of. 

From there, I never looked back. Anthropology was a thing of the past and web development with ColdFusion was the way forward. And I could not be happier about how it all unfolded. 

From VPS to the Cloud (AWS): Setting up an AMI for Railo

From VPS to the AWS Cloud

As I mentioned in one of my last posts, my primary client and I have undertaken a mission to make the application kronum.com more scalable and nimble, as we are experiencing sudden and dramatic spikes in our traffic.

The process of migrating from a traditional VPS stack to a nimbler Cloud setup has been quite educational and illuminating. It definitely alters how you view the architecture of your application. It’s hard but fun.

Disclaimer

I want to call out that I am new to this AWS world and recognize that some or many of the options I’ve selected may not be ideal or the best ones. I did my best to research it thoroughly and make good choices.

Build the AMI YOU Want

I’ve been mulling over how to approach this series and, as if often the case, I find myself typically searching for similar topics over and over. One thing I often check for is how to install things on a Unix server. So, I wanted to detail how I built our current server on AWS, what services I chose to install, how I configured them and how it’s played out.

I suppose the best place to start is to list off what we’ll install and in which order these services will be installed. Please note that our production instance is a large 64-bit Ubuntu machine while the one I’ll create below is for our staging system and will be a small 32-bit machine. Despite the differences in instance type (large v. small) and bit (64-bit v. 32-bit), the process for installing and the software chosen is identical.

The Amazon Machine Image (AMI)

I chose the pre-built Amazon Linux AMI made available publically via the AWS console. For the purposes of this blog post, I chose this image because it’s a minimal Linux install (you don’t need to remove lots of options/software from some of the other available images) yet has the AWS configurations built in.

With my server chosen and running, I set out to begin installing the services I would need to run our application. In order of installation, they are:

  • Apache Tomcat 7.0.x
  • ActiveMQ 5.5.x
  • Apache 2.2.x
  • Railo 3.3.000.x
  • VFTPD (ftp)
  • Postfix (mail)

Picking an Instance

  • Log onto AWS and select the EC2 tab
  • Click the Launch Instance button
  • Select the Amazon Basic 32-bit Amazon Linux AMI 2011.02.1 Beta (note: the date may change depending on when Amazon makes updates and this post is read)
  • Follow the Request Instances Wizard steps to complete the setup of your AMI
  • You should probably pick the Small instance (a few bucks per month) or the micro (free) unless you know you want a large instance (more money)
  • It will take a few minutes but, in short order, your instance will be up and running

The instance wizard looks like this (and we’re using the top AMI in this screen shot): Instance Wizard

Elastic IP

One thing to note about AWS is that each time you shut down (versus reboot) your instance, the IP address assigned to it will ‘go away’ and upon your next boot, a new one will be assigned. This can be a pain in the ass for SSH connections, FTP, DNS, etc. To get around this issue, AWS has Elastic IP addresses. These IPs are static in that AWS allocates them to you. What’s cool is that you can assign this IP address to any instance you want … and it will persist beyond stop/starts.

Getting started with an Elastic IP is quite easy.

  • Select the Elastic IP link on the left-hand side of the EC2 page (under the section for Networking & Security)
  • Press the button to allocate a new IP address and follow the prompts
  • Select the Elastic IP in the grid
  • Click the now-enabled button: Associate Address
  • Select your instance identifier from the select list

Now you have a static IP from which you can access your server.

Installing the Software/Services

The first step to installing your software is to connect to the server itself. I use my Terminal and connect via SSH. For help doing this, return to the Instances section of the EC2 tab and select your instance in the grid. Then, expand the Instance Actions menu and select Connect. This will show you the SSH details. If you’re not familiar with SSH and PEM key files, spend a few minutes learning about them.

Once connected to your instance, you’re ready to install. To make your life easier for the installations, type ‘sudo su’ (no quotes) at the prompt so you are now working as the super-user.

Next Post

In order to keep the posts fairl readable, in terms of length, I’ll stop here and create a new post, which I am working on now, for the actual installations.

CFML Many-to-Many ORM Gotcha ... Well, It Got Me!

Many-to-Many’s

I’m working on a few ORM entities in a client’s application tonight and came across an error that baffled me for a bit longer than it should have! I thought I would post it just in case someone else comes across it.

I have two entities: Teams and Sessions. A team can play in many sessions and a session can have many teams. They are joined via a link table in the DB. That table, SessionsTeams, has two columns: sessionid and teamid. It’s nothing more than a basic many-to-many relationship.

The problem was that every time I attempted to load the entities the application threw an error: invalid column name ‘teamid’. After some searching and failed attempts at fixing the issue via the fkcolumn and inversejoincolumn attributes, it hit me that those attributes were fine and I was, simply, assigning the wrong column name to the orderby attribute. Here’s where I went wrong:

CFC Entities

// Team.cfc
component displayname="Team" alias="Team" output="false" accessors="true" persistent="true" entityname="Team" table="Teams"{ 
    property name="ID" type="string" ormtype="string" column="id" generator="assigned" fieldtype="id";
    property name="name" type="string" ormtype="string" column="name";
    property name="sessions" type="array" fieldtype="many-to-many" CFC="Session" linktable="SessionsTeams" FKColumn="teamid" inversejoincolumn="sessionid" lazy="false" remotingFetch="true" cascade="all" orderby="team_id";   
    public Team function init(){
        return this;
    }
}   
// Session.cfc
component displayname="Session" alias="Session" output="false" accessors="true" persistent="true" entityname="Session" table="Sessions"{     
    property name="sessionID" type="numeric" ormtype="integer" column="id" generated="insert" generator="native" fieldtype="id";
    property name="sessionTitle" type="string" ormtype="string" column="session_title";
    property name="sessionTeams" type="array" fieldtype="many-to-many" CFC="Team" linktable="SessionsTeams" FKColumn="sessionid" inversejoincolumn="teamid" remotingFetch="true" lazy="false" cascade="all" orderby="id";          
    public Session function init(){
        return this;
    }
}

Ah-ha!

I mistakenly thought that the orderby attribute is meant to reference a column in the link table and not the source table. So, changing the orderby to reference the ‘id’ column/property in the source entity solved the issue.

// In Team.cfc
property name="sessions" type="array" fieldtype="many-to-many" ... orderby="id";
// In Session.cfc
property name="sessionTeams" type="array" fieldtype="many-to-many" ... orderby="id";

When I was learning about creating the many-to-many relationship with CFML’s (Railo in my case) ORM, I never saw details in the docs about this attribute. So, I thought I’d post my screw-up story in the event someone else ends up down the path I took (and I hope no one does ;–).

Migrating a Railo Application from a Traditional VPS to the Cloud (AWS): It Begins

This has been a very exciting week with the Kronum project (kronum.com). Kronum is a new entry to the American sports scene. It's a mashup of several different sports (basketball, soccer, and others) played on a circular field outdoors. Over the past two weeks, we've seen our web traffic go from ~200 visitors per day to 13,000+. What happened to increase our traffic so dramatically and so quickly? The beauty of the viral web is what happened.

About 10 days ago, we got tweeted about from actor Rob Lowe and that's where it seems to have started. From there, Kronum ended up featured on Wired, then on ESPN Sportsnation's Facebook page and will soon be featured on the Sportsnation TV show as well as in ESPN the magazine. While the Lowe tweet got the ball rolling, the Wired article really upped the ante. We broke 30,000 visitors in the 24 hours after that story was launched.

All in all, this initial load was handled fairly well, especially given the nature of the site (more on that below). There were two server crashes during this traffic: one was a result of a corrupted CouchDB cached document and the other was Apache HTTPD failing because of too many concurrent requests. Both of which were easy enough to resolve.

However, the rapid spike in traffic and the consistent trending of Kronum across the intrawebs and other traditional media led the Kronum team to reevaluate their infrastructure. The team realizes that they are on the cusp of things really taking off and that what happened in the past two weeks was nothing compared to what is (hopefully) coming.

The Kronum League is about to begin their first recreation league session in Philadelphia, where the sport is located and headquartered, and its third official, professional season of the sport starts later this summer. The start of these seasons, coupled with the growing media and web attention, should provide an even greater spike in traffic over the coming months. 

My part in all this is really small. I am the (only) guy responsible for three large areas of the application: back-end code, the database, and the servers. Okay, not really a 'small' part, huh? 

Here's where we are today.

The Web and DB Servers Specs:

  • Railo 3.2 (with BlazeDS)
  • Apache Tomcat 7 (64-bit)
  • Apache HTTPD 2.2.15 (32-bit)
  • MS SQL Server 2008 Web edition
  • Apache CouchDB 1.0.2 (for cache)
  • Apache ActiveMQ 5.4.1 (for messaging)

The Code/Application: 

  • Back-end written in CFML with no framework
  • Java used in specific spots for handling ActiveMQ messaging and connections
  • CFTracker 2.1 to monitor memory and sessions on our application
  • Front-end is a 100% Flex/Flash application

Server I:

  • Win2K3 R2 64-bit (SP 2 installed)
  • 8 GB RAM
  • Intel Xeon Quad 2.33 GHz Processor
  • ~400GB of disk space
  • Primary role is that of the web server (Apache HTTPD, Apache Tomcat, and Railo)
  • Secondary role is that of a DB server for our staging site

Server II (this server was added about a year after Server I):

  • Win2K3 R2 64-bit
  • 8 GB of RAM
  • Intel Xeon 8 core 2.4 GHz Processor
  • ~400GB of disk space
  • Primary role is that of a DB server (SQL Server 2008)
  • Secondary role is that of a web server for our staging site

As you can see, the server is pretty beefy, which might beg the question, "Why move and why move to AWS in particular?" The primary motivation is twofold: (1) a move to AWS will reduce the existing server costs by ~35% and (2) the application needs to be nimble for these spikes in traffic. It is this second motivation that is truly driving the change (though the fact that we could now run 2 web servers and 1 dedicated DB server for the same price as the current hosting cost doesn't hurt).

Disclaimer: I will not name our current web host because our transition has nothing to do with them. They have been fantastic to work with and do a great job of responding to requests, etc. The move is entirely to save some money and, as I said above, to be more nimble in times of heavy load.

The Application's Problems:

  • The front-end of the site is built entirely in Flex/Flash and is VERY graphic intensive (it is not just large graphics ... it sends 100s of graphics to the client).
  • The front-end is made up of 4.5 MB of Flash SWFs (the main SWF and accompanying modules), not counting the aforementioned images/graphics. 
  • Caching is barely used at all on the front-end (e.g., the homepage alone sends 6.3 MB of graphics to the client, of which only 847.7 KB worth are grabbed from cache). 
  • The back-end, which I inherited and unfortunately, had to follow, is a horrible mess of objects. There are remote services for Flex connections but these remote services then call internal services that then do all the work (and those services then call various DAOs, other services and VOs/Beans). Given that one of CFML's weaknesses is the speed at which objects are created we create a boatload of objects unnecessarily with each request.
  • There are many expensive database calls and there is not a really great way around them (more sql-tuning, sure, but it's one of those "they are what we thought they would be" things ... ass kickers :).
  • There is minimal caching on the back-end (not for my lack of wanting to implement it).
  • We server all our images from the local web server (videos are streamed from a CDN).

The Server's Problems:

  • They are pretty expensive (not to say that they are undervalued).
  • It takes a good bit to get another server setup, configured and running (1-2 business days)
  • We are locked into SQL Server 2008 Web edition, which lacks replication, unless we want to pay ~$17,000 for the Enterprise license on our two DB server installs. 
  • We prefer Apache servers and they simply do not run as well on Windows as they do on Linux.
  • The Win2K3 OS takes away precious server resources not as readily lost in a Linux server.
  • Security is tougher on Windows than Linux (note this is a comparative statement and not a statement that there are no security issues on Linux) and while this is handled admirably by our current host, it's still a point of concern, albeit a minor one.

We are now in the process of migrating to Amazon Web Services (AWS). We have setup our initial machine image (AMI) with the following:

  • Large Instance (64-bit, 7.5 GB RAM, 850 GB disk, 2 virtual cores with 2 EC2 compute cycles each, and high I/O performance)
  • Ubuntu 10.10 Server 64-bit
  • Sun/Oracle's JDK 1.6.0_24 64-bit
  • Apache HTTPD 2.2.x (I forget the exact rev) 64-bit
  • Apache Tomcat 7.0.12 64-bit
  • Apache Tomcat Native Connectors 64-bit
  • Apache CouchDB 1.0.1 64-bit
  • Apache ActiveMQ 5.5 64-bit
  • Railo 3.3 (w/ BlazeDS, of course)
  • VSFTP
  • openSSL
  • The code base
  • EBS volume tied to our AMI

Next up, we'll be making the following changes and migrations:

  • Complete testing and tuning of new AMI and flip the switch to use this server (Saturday night is the 'big date').
  • Migrate the SQL Server 2008 DB to MySQL 5.1.x running on Amazon's RDS, which supplies replication and backups as part of the service as well as failover protection! In the short run, we will continue to use our SQL Server DB from our existing server with the new site server.
  • Migrate sending mail from the application to Amazon SES.
  • Begin to serve our images and other static content from S3 (it's already been set up on S3).
  • Utilize Amazon's CloudWatch service to auto-scale the site as needed.
  • Setup the Elastic Load Balancer.

Over the next couple of weeks, I'm going to be doing some posts in the following categories:

  • Getting started on AWS for CFML applications (i.e., building your server, installing software, configuring the server for security and performance, getting ActiveMQ and Tomcat to talk)
  • Migrating from MS SQL to MySQL on RDS
  • Load testing your site
  • Scaling on the cloud
  • Kick-ass OSS CFML applications to help you run a better site (CFTracker and Hoth in particular)
  • Refactoring your CFML code (i.e., transition to S3 for serving static content, cache the shit out of your app, get rid of overly complex OOP in favor of lighter and nimbler OOP, integrating ORM into an existing, non-ORM application, tuning DB queries when ORM is not enough) 

This migration is a pretty huge and really cool project; one that I am very excited to be a part. If there is something else involved in making such a transition please let me know and I can add it to my list of forthcoming posts. If you have any other questions on what we're doing and why, please don't hesitate to send me a note or drop a comment. 

Railo/CFML Spreadsheets Made Easy (Well, Easier, Really)

Spreadsheets Made Even Easier in Railo

First and foremost, I want to give a huge shout out and thanks to Andy Jarrett (@andyj and Blog ) for his work on the tag & functions extension for Railo. His work on this extension, and making it publicly available for all of us, just made my life infinitely easier.

The Problem

My client wanted to get a list of all members on his site who have logged in over the last year. He wanted to know how many times each user logged in each month over the previous year (previous year being determined by the current date). He wanted the data presented in an XLS file, sorted from the most logons to the least.

The Solution

We all know that there are plenty of ways to go about creating a spreadsheet from CFML and none of them are too awful. However, I needed something that would be very easy and fast because I knew the data was going to be a bit of a bear to work with and time was limited. The new CF9 spreadsheet functionality fit the bill, however, it has not yet been incorporated into the Railo core.

At the database level, I had some fun creating a couple of UDFs and a View so that I could easily call for this data from CFML. No problems here. Okay, I’ll confess that the view and udfs were a bit tricky … but they were fun problems to solve (NERD ALERT :)!

Enter Andy’s extension. To start, I had to install the extension on Railo (duh). Like the update process for Railo, it’s incredibly easy to add extensions to your Railo server. Since Andy wrote up all the basics needed for installation on his blog, you should check out his post http://www.andyjarrett.co.uk/blog/index.cfm/2011/¼/cfspreadsheet-for-Railo-update for installation/setup details.

Once the extension was installed and the server restarted, which took a few minutes tops, all of CF9’s spreadsheet functions and the cfspreadsheet tag are now at my disposal in Railo.

From here, it took me ~10 minutes to write and test the code that would generate and output my XLS file … and this is all the code it took!

CFMLove

I love the fact that CFML (and Andy’s extension!) allowed me to spend the majority of my time working on the data and, once I had that sorted, I did not have to eff around trying to figure out how to present it. That part was easy and just freaking worked!

If you need to do some spreadsheet output and you’re on Railo, be sure to checkout the extension. I’m pretty sure you’ll be as stoked about it as I am!