ColdFusion 10 with Tomcat brings back Context Root Routing

A common approach in the distant past was to use the JRun connector to route requests to the right server based on context root mappings.  This was possible in JRun 4 Connectors up to the JRun 4 updater 2. 

 
The usual scenario was that companies would use one root folder then separate the code with application names using a /appname convention, such as adobe.com/birds or adobe.com/dogs.  For each application you would then have a CF server instance. The company could then use one web site, with one connector setup, to distribute requests to as many servers as you wanted all based on the application name.  After JRun4 Updater 2 you needed to define a separate web site and separate connector in order to handle distributing load.  I know this affected a few customers as they upgraded.
 
The good news is that this type of setup is back again using the ColdFusion 10 Apache Tomcat Connectors.
 
The keys to making this work are making edits to the Connector properties files once you have setup your initial connector.
 
After you have created your first Connector setup go into C:\ColdFusion10\config\wsconfig\1\worker.properties and add worker processes for each one of the CF Servers you want to have requests routed too.
 
The file will look like this with a connector setup for the cfusion server:
<code>
worker.list=cfusion
worker.cfusion.type=ajp13
worker.cfusion.host=localhost
worker.cfusion.port=8012
worker.cfusion.max_reuse_connections=250
</code>
You want to add the same set of settings for each server.  If you don't know the port, you can find that it in the C:\ColdFusion10\<servername>\runtime\config\server.xml file.
 
An example of a new server would look like the below:
<code>
worker.list=reports
worker.cfusion.type=ajp13
worker.cfusion.host=localhost
worker.cfusion.port=8013
worker.cfusion.max_reuse_connections=250
</code>
Once you have all your servers defined you now need to tell the Connector what mappings go to what Worker.  Let's open up the C:\ColdFusion10\config\wsconfig\1\uriworkermap.properties file.
 
The default file looks like the below:
<code>
/cfformgateway/* = cfusion
/CFFormGateway/* = cfusion
/flex2gateway/* = cfusion
/flex2gateway = cfusion
/cffileservlet/* = cfusion
/CFFileServlet/* = cfusion
/cfform-internal/* = cfusion
/flashservices/gateway/* = cfusion
/flex-internal/* = cfusion
/rest/* = cfusion
/*.cfml/* = cfusion
/*.mxml = cfusion
/*.as = cfusion
/*.cfm = cfusion
/*.cfm/* = cfusion
/*.swc = cfusion
/*.cfml = cfusion
/*.cfc = cfusion
/*.cfc/* = cfusion
/*.cfr = cfusion
/*.cfswf = cfusion
/*.sws = cfusion
/*.jsp = cfusion
/*.hbmxml = cfusion
</code>
As you can see all the mappings are going to the cfusion Worker.  We want to replicate these mappings to have them recognize our application names and be routed to the corresponding Worker setup in the workers.properties file.
 
Important notes about this file, all the mappings are case sensitive.  Also, make sure the cfusion map grouping is last if it is going to act as the default server.
 
To make this all work we need to copy the set of cfusion mappings and create new ones for all our Workers we have set up.  Here is an example set of mappings for a new server:
<code>
/www.yourserver.com/reports/cfformgateway/* = reports
/www.yourserver.com/reports/CFFormGateway/* = reports
/www.yourserver.com/reports/flex2gateway/* = reports
/www.yourserver.com/reports/flex2gateway = reports
/www.yourserver.com/reports/cffileservlet/* = reports
/www.yourserver.com/reports/CFFileServlet/* = reports
/www.yourserver.com/reports/cfform-internal/* = reports
/www.yourserver.com/reports/flashservices/gateway/* = reports
/www.yourserver.com/reports/flex-internal/* = reports
/www.yourserver.com/reports/rest/* = reports
/www.yourserver.com/reports/*.cfml/* = reports
/www.yourserver.com/reports/*.mxml = reports
/www.yourserver.com/reports/*.as = reports
/www.yourserver.com/reports/*.cfm = reports
/www.yourserver.com/reports/*.cfm/* = reports
/www.yourserver.com/reports/*.swc = reports
/www.yourserver.com/reports/*.cfml = reports
/www.yourserver.com/reports/*.cfc = reports
/www.yourserver.com/reports/*.cfc/* = reports
/www.yourserver.com/reports/*.cfr = reports
/www.yourserver.com/reports/*.cfswf = reports
/www.yourserver.com/reports/*.sws = reports
/www.yourserver.com/reports/*.jsp = reports
/www.yourserver.com/reports/*.hbmxml = reports
</code>
 
I found that the /appname was not enough to catch the request, it required the full domain.  That was disappointing since you will need to change them based on environment and also deal with case sensitivity and whether they have www. etc.
 
You can remove all the mappings your applications does not plan to use.  The mappings are worthy of a separate post themselves.
 
Once both of these files are edited simply restart your web server and test.  I have read that Tomcat does check for changes and reload them every 60 seconds, but I never tested that approach.
 
 
To test I placed a cftrace tag inside each application to tell me the server.coldfusion.rootdir to verify I was getting to the correct server. I used IIS for all my testing but I think Apache should be very similar, if not identical. 
 
There you go,  Context Root Routing, one web server with one connector to as many ColdFusion servers as you want.