Distracto-boy meets layout=plain

Written by jbriccetti on . Posted in App Dev, Architecture, Misc Ramblings

I’m a huge fan of UI frameworks – particularly Twitter Bootstrap and jQuery UI – and I love making things look great – these frameworks really help me do that. Basically, I’m a wannabe designer. I admit it.

A simple bootstrap-infused login form

a bootstrap styled list view

Some days, i just spend way too much time on getting those buttons, just right, or the right table or grid layout – it can be a time-sucker and I sometimes find myself behind on a deadline because I spent too much time pushing around the UI and not enough time building the “application” code. Enter: layout=plain.

In the CF Wheels framework, a Rails-like approach to CFML development, the base controller class (/controllers/Controller.cfc) has an init method where most folks handle all the pre-processing needed for all requests. We scaffold our CF Wheels apps from our  TroyWeb1 base-build – which includes a “filter” in the base controller to handle  initialization and cleansing of request parameters as well as setting up defaults for the built-in params used by wheels for layout and format.

<cfscript>
	firewall();
	cleanseAndStrip(params);
	param name="params.format" default="html";
	param name="params.layout" default="";
	switch(params.layout) {
		case "plain":
			usesLayout("/plain");
			break;
		default:
			usesLayout("/bootstrap");
	} //end switch
	if(params.format EQ "xml" || params.format EQ "json"){
		get("cfsetting").setEnablecfoutputonly(true);
		get("cfsetting").setShowdebugoutput(false);
		set(showDebugInformation=false);
	}
</cfscript>

Like most app dev frameworks, CF Wheels leverages a front controller design pattern. That means all requests get routed through the same initial channel and that means certain things can easily be managed in that initial routing – like format and layout, which in CF Wheels are parameterized so the request can dictate what format needs to be returned. This is really great in the world of JSON feeds or other syndication streams. Thus, add ?format=json to the url and the plumbing to route your call to a json generating view is all built in. [checkout provides()] Layouts are managed this way too when combined with the usesLayout() controller method.

If you too are mesmerized by the shiny, candy-like buttons, join Distracto-boy in the fight. Create /views/plain.cfm with one line of code:

<cfoutput>#includeContent()#</cfoutput>

and simply change the default for params.layout to “plain”

	param name="params.layout" default="plain";

and there ya go. Badabing! all those distractions are gone and you can focus on creating the app without all that glitter.

layout=plain rendering of the same form

layout=plain on the same list view

Dealing with Case Sensitivity of Database Table Names at the Persistance Layer with Hibernate

Written by Sean Ryan on . Posted in App Dev, Architecture, Gotchas, Strategy

It’s been a while since my last post so it’s about time I got back to it since I’m backlogged with all sort of awesomeness.

Recently, I took over a pretty big Spring project. Lucky for me, it was written largely in Spring 3.0 so my periodic upgrades to 3.1 haven’t been too difficult. I’m the only developer on the project but it’s not that bad (anymore) and it’s given me a chance to really focus on my Spring skills.

Since I develop locally, I backed up the production database on the server and brought it down to my laptop. Before I could work on it, I needed to run the data through a conversion routine that migrates the database model and its data into the new and improved model for the next release.

The Problem

The problem is that the server is Linux and my computer is a Mac.

Why does this matter? It matters because each OS has different case sensitivity. The conversion routine uses Hibernate as the persistance provider and it’s configured to use the DefaultComponentSafeNamingStrategy which maintains the same case as the managed entities. This is fine except that the application uses a custom naming strategy that converts everything to lower case and acts as a wrapper around the DefaultComponentSafeNamingStrategy. The only time this would ever cause a problem is when the operating system the application is run on is case sensitive. Linux is but Windows is not case sensitive and neither is Mac. I didn’t know this. In fact, I was under the impression Mac was a good OS.

Any of my collegues reading this right now are smiling because I’m constantly listing the ways Windows is terrible and Macs are better as programming tools.

The Effect

This problem wasn’t actually a problem on Windows or Mac. It manifested itself when I moved my converted data up to the server and restored it into the database. When I fired up the application, all the data was gone! Pretty sure a pink slip was in my future, I scrambled to figure out what happened. This was the first time the data was updated since my firm took over the project and they had put their faith in my ability to not blow the database away. I had just blown the database away, or so I thought. It took a while to figure out what happened.

As it turns out, the data was there but with camel casing but since the app uses a lowercase naming strategy, it wasn’t able to find any of the tables.

For example, a table named MyWidgetTable was being looked for under the name mywidgettable.

Finding the Best Solution

This might seem like an easy fix, just update the naming strategy for the conversion routine. It’s true, that’s the best solution and the one I selected but, it’s important to realize why it’s the best solution.

For instance, another option would be to configure the database – in this case, MySQL – to use lowercase naming when creating objects. People do this. You can read more about that here http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html.

Although this is an option, I don’t recommend it.  Doing so will more tightly couple the database implementation to the application and whenever possible we like to make each tier in an architecture as pluggable and removable as possible.  Changing databases has more side effects when you start introducing configurations that directly impact the design of a system.

In general, when you need to deal with filesystem objects, try to choose an implementation that will work across the big players to keep your code as portable as possible even when you think you’re environment won’t change. It will and in this field, crap changes every couple of days! The previous developer knew this and that’s probably why he wrote the custom lower case strategy to begin with.

Multihoming with Multiple Instance ColdFusion 9 with Apache 2 on Mac OS X

Written by Sean Ryan on . Posted in Architecture

Multiple Instance ColdFusion has a number of advantages that reach beyond the obvious benefits to a large scale, high traffic, production server farm.  As a consultant, I have multiple clients and some clients have multiple web sites and web apps.  My clients aren’t related, so why should I configure a single local instance of CF to handle all of their apps and web sites? That would be a configuration headache since with a single instance, you also have a single CF administrator.  Suppose one client uses CF sessions and other uses JSessions and for whatever reason, that cannot change. If you’re anything like me, you’re jumping from client to client and can’t be worrying about logging into you local CF admin and resetting it to mirror that client’s environment. Enter multiple instance ColdFusion…

Documentation

I’m writing this entry because I found the documentation on configuring and managing multiple instances -at times – confusing, lacking, or not what I needed at the time.  In the end it turns out to be fast, simple, and as user friendly as a server administrator could really ask for.

Download and Install ColdFusion

This might seem like a useless sections but if you’ve never installed the multi-instance version, you might wonder why you can’t find it easily. It’s just the developer edition – nothing special. Just choose multiple instance when you step through the wizard.

Visit Adobe’s ColdFusion Web site to get the latest version (9 as of this writing).

I grabbed the 64 bit version for Mac OSX.

Here are the screen shots for the most relevant wizard screens during installation.

Assuming all went well, you now have a single instance of a multiple instance ColdFusion server installed. Unlike the the standard single instance install, the URL of this one is not localhost:8500, but rather localhost:8300.

New Server Address

After the installation is complete, you have one instance name cfusion that serves as the primary administrative instance on your computer. The cfusion instance is like the single instance you may be used to except it can do more (like create and manage other instances).

The administrator is located at a new address:

http://localhost:8300/CFIDE/administrator/index.cfm

New Server Location

If you chose the default parameters during installation, your JRun server is located in /Applications/JRun4. In the JRun4 directory, you will find the servers directory and inside that, you will find a cfusion directory (/Applications/JRun4/servers/cfusion).

Each time you create an instance using the cfusion administrator, it will end up in the servers directory, unless you explicitly tell it otherwise. The reason: ColdFusion is actually just a J2EE Web Application deployed to a servlet container – in this case, JRun4. In future releases of ColdFusion, Tomcat will be used in place of JRun.

Server Directory Layout

The layout of the directory is slightly different than that of a single instance.

Document Root: /Applications/JRun4/servers/cfusion/cfusion-ear/cfusion-war

When ColdFusion is installed in multiple instance configuration, each instance is created and deployed as an EAR file. An EAR file is an Enterprise ARchive file that contains one or more J2EE modules along with instructions for how the modules are to be deployed. We are interested in the document root, CFIDE, and WEB-INF.

Creating an Instance

Let’s create a new instance using the cfusion administrator. It will serve as a template for new instances when they are created. By default, when a new instance is created, the settings from the cfusion instance are copied to the new instance. This includes data sources and mappings.  I’ve experienced a mix of results with this so be sure each instance is configured how you want.  A benefit of multiple instances is that you can have different settings so this might not be what you want anyway.

Open the cfusion administration page and click Instance Manager under the Enterprise Manager menu option on the left.

This page lists all instances that you have installed and on which port they run whether or not they are running now.

Click New Instance and give your instance a name. As you can see, you can point to an EAR or WAR file but we’ll let the administrator create the instance for us so leave that blank.

Click Submit.

After the instance is created, you can view the list of servers and see your new instance.

Notice that the instance may not be started by default. If not you’ll have to start it manually. Also note the port, 8301. Each instance is assigned the next available port beginning at port 8300. Since the cfusion instance run on 8300, the next available port is 8301.

NOTE: If you have a server running on ports 8301, 8302, and 8303 and the delete the server on port 8302, the next available becomes 8302. As such, the next instance will be assigned this port.

The administrator URL for your new server is http://localhost:8301/CFIDE/administrator/index.cfm

The document root of your new server (assuming you also named your server ‘bar’) will be /Applications/JRun4/servers/bar/cfusion.ear/cfusion.war

Apache Web Server Connector

Normally, users aren’t hitting your ColdFusion server directly. Under typical use, a web server hands requests for ColdFusion pages off to the ColdFusion server and requests for other types files are handed off to some other application server.

Start apache by running:

sudo /usr/sbin/apachectl start

Start the web server configuration tools that ships with ColdFusion by running the following command:

sudo java -jar /Applications/JRun4/lib/wsconfig.jar

Click Add…

Select the instance you want to connect and specify the location of Apache’s httpd.conf file. In my case, I’m using Mac’s built-in apache web server.

Be sure to check Configure web server for ColdFusion 9 applications.

Click OK and you will see a message to restart apache. Click Yes and your Web server will be connected to your new instance of ColdFusion. All connected instances will be listed in the Configured Web Servers dialog box. Close the dialog box.

Now we test the Web server and the ColdFusion instance to be sure it all worked.

Test Apache

Once apache has been restarted, it will be configured to hand off ColdFusion requests to your new instance. To test apache, we’ll put a sample HTML file in the document root of the Web server. For me, that is located in /Library/WebServer/Documents.

All I’ll do is change the text in index.html.en to Hello from Apache2!. Since Apache is configured to look for .html files before .cfm files, this will be served when the root directory is requested.

Test that the Web server serves this by going to http://localhost/

Test ColdFusion Instance

To test that your ColdFusion pages are being served properly, add an index.cfm file to your instance’s root. Recall, this is /Applications/JRun4/servers/bar/cfusion.ear/cfusion.war

View the page at http://localhost/index.cfm and you’ll see the ColdFusion page.

Configuring Apache for Multihoming to Multiple ColdFusion Instances

Perhaps the most necessary piece of understanding is how to specify which ColdFusion instance handless requests for particular ColdFusion page. With multiple ColdFusion servers, how to we know which server to direct to?

Create a New Instance

Create a new ColdFusion instance named foo and create a directory of the root named “my-resource-killer-app” and place in it, an index.cfm file.

Test that you can see the page before continuing.

Notice that the port number of this instance is 8302 (the next available from 8300).

Configure Apache

You can’t use the Web server configuration tool to link this new instance since the purpose of the wsconfig.jar program is to connect a Web server – we already have one connected. We need to manually edit the configuration file to get it to talk to the new instance sometime and the old instance (bar) other times.

sudo emacs /etc/apache2/httpd.conf

Look for the following section:

 

This is part of the configuration that the tool added when we ran the Web server configuration tool. It tells Apache to hand off requests for .jsp .jws .cfm .cfml .cfc .cfr .cfswf files to the JRun server.

Note the following line:

JRunConfig Bootstrap 127.0.0.1:51000

This is the location of the connection between the Web server and the ColdFusion instance. We need to know the location of the new instance (foo) that we can use it in our next step. To find it, we’ll need to take a look a the JRun Administrator.

Start the JRun Admin web App

Run the following command to open the JRun instance launcher:

/Applications/JRun4/ColdFusionLauncher.app/Contents/MacOS/ColdFusionLauncher

Notice the admin JRun server (not running) on port 8000. Click on it and click start.

Go to the admin app in your browser:

http://localhost:8000/

The user name is admin and the password is the same password you’ve been using to log into all your ColdFusion administrators.

We are interested in the Proxy Port column here. Note our bar instance is running on proxy port 51000.  Equally important, our new foo instance is on proxy port 51002.

Remember that port.

Note: If for some reason, the proxy service is running, your Web server will not be able to connect to your instance so double check that it is in fact running by clicking on Services under the bar instance on the left side navigation. Ensure that the ProxyService is running. If it’s not, start it.

Return to your Apache configuration file and make three changes…

Comment out two lines from the configuration shapshot shown above

uncomment the following line:

Modify the following <Directory> directive.

Open the httpd-vhosts.conf file for editing.

sudo emacs /etc/apache2/extra/httpd-vhosts.conf

You’ll need to configure a Virtual Server (virtual host) for each instance that will be handling requests from this Apach server.

Change the Virtual Hosts section to something like what I have below. Use the values that that appropriate for your configuration – obviously.

Notice that all requests for ColdFusion resources at killerapp.localhost will be handled by the foo instance and all requests for ColdFusion resources at localhost will be handled by the bar instance.

Also notice that the proxyport 51002 is set for foo. BE SURE THE PROXY IS RUNNING!

Modify Hosts File

Before we can test this on our computer, we have to modify the hosts file so that the address killerapp.localhost will loop back to 127.0.0.1 for our apache Web server to handle. This is only necessary when you aren’t running your own DNS server. Which, if you are – very cool, nerd.

Test!

Now that you’re all configured, test both URLs.

First, the standard localhost address that we changed to a virtual host.

Next, the killerapp.localhost that points to foo.

Wrap Up

Being able to isolate Web sites or even Web apps allows us several advantages. Since each instance runs as a single server, the server can be tweaked to perform optimally just for that site or application.  Moreover, applications and sites no longer need to run on the same physical machine or virtual machine. This overcomes limitations like memory, processor core allocation and disk space.

Our example offloaded a resource intensive ColdFusion application to a new server (bar) so the rest of the site wouldn’t be affected by requests to the app. This is very typical but it doesn’t have to be just an app. Entire sites, can be treated this way. For example the following fictitious sites can all be severed from the same Web server but reside on separate physical instances of ColdFusion:

  • http://company.net
  • http://hr.company.net
  • http://it.company.net
  • http://sales.company.net
  • http://me.company.net
  • http://careers.company.net

Multihoming is a popular configuration for serving ColdFusion pages from multiple instances. I don’t run this configuration on my local development machine but it is something that clients may require and a solid understanding of what’s going on under the hood is always a good basis to pitch your ideas to a client. Problems pop up along any step and being able to overcome them is rooted in logic. We’re developers, that’s how we think anyway 🙂

Hope this helps.

CFWheels Workarounds Numero Uno – Application Proxy

Written by jbriccetti on . Posted in Architecture, Misc Ramblings, Software

One of the interesting features of the CFWheels framework is the fact that the core application architecture leverages <cfinclude /> tags.  I say interesting because in an environment that is essentially java under the hood, most frameworks use inheritance. Such is the case with FW/1 (“Framework One”), the awesomely simple to use framework from Sean Corield

FW/1 implementation of Application.cfc

<cfcomponent extends="org.corfield.framework">
</cfcomponent>

CFWheels implementation of Application.cfc

<cfcomponent output="false">
   <cfinclude template="wheels/functions.cfm">
</cfcomponent>

In many ways, how it is wired in doesnt really matter… and <cfinclude /> is lighting fast, much faster than inheritance. The challenging part becomes when you want to override (or extend) a method in the core application framework – you can’t just create the method and use super.method() as needed. Instead, wheels creates a way for you to piggyback onto the application events, but at that point you are at the mercy of the framework and whatever code it already ran – there is no obvious way to orchestrate the firing order. your custom code comes last, done deal.

But of course where there is a will, there is a way. while it would be a big no-no to hack the framework code itself (in the wheels directory) the answer is quite simple. simply rename your root Application.cfc file (coded above) and name it “Wheels-Application-Proxy.cfc” Then, just create the following Application.cfc in your root directory

<cfcomponent extends="Wheels-Application-Proxy">
</cfcomponent>

Now if you want to rewrite the OnRequestEnd event (say to modify that ugly debug information wheels gives you, or perhaps tweek it a bit) you are ready to go.  In such a case you may want to be careful… if you aren’t going to call super.OnRequestEnd() at some point in your method, you may want to have a peak in the framework code and see what its doing and be sure you dont cut out any fundamental framework code… but that’s easy enough to do with a copy-and-paste