Wednesday, December 29, 2010

CF: Railo 3.2 Released

After much work the Railo team released the new version (3.2) of Railo over Christmas.
Railo is one of the Open Source ColdFusion application engines available. The other notable one is Open Blue Dragon.
If you are doing ColdFusion based programming this is something that should belong to your stable of tools that you are familiar with.
In the past the discover-ability of Railo was harder as it was not as easy to understand how to get things going once you downloaded it. Though technically simply the step of getting it installed and going was a hurdle that made it harder than the Adobe engine.
With this release among a myriad of enhancement installers were made available for multiple platforms. For example, for the windows platform the comparable Railo installer is one third the size of Adobe's while it handles both 32 and 64 bit installations.

Happy Experimenting,
B.

Wednesday, December 1, 2010

XJS: Using the debugger command to start a debugging session

The ability to kick of the an in-line step-by-step debugger was introduced in JavaScript early on. Since before JS version 1.5, I believe. However, practically speaking there were few client-side debuggers that could take advantage of this.
Thus, the use of it has not been heavy even after the more ready availability of Browser development support and in-line debuggers. Today, all browsers support some sort of step-by-step debugger that can be used in concert with the debugger command to more effectively debug code, so perfect time to remind us of this option.

Why would we need to use it?. Let use this snippet as an example:

for (var i=0; i <= 10000; i++) {   
if (i==98) {

debugger;
}
}
Using conventional in-line debugging you would have to set a break-point, then iterate along until you reached the loop condition that you were interested in, i.e. 98. Using the debugger statement, you simplify this drastically.

Expanding this principle into use with ExtJS is easy. Giving the nested nature of much of the ExtJS code and heavy use of complex configuration objects setting breakpoints is sometimes a game of hit-and-miss.
Using the debbuger statement you will still able to halt the execution at the right place even if you did not hit the correct break-point in your debugging tool.

For example:

 1: listeners: {
2: render: {
3: fn: function(){

4: //stop for debugging here
5:
debugger;
6:
7: Ext.fly(clock.getEl().parent()).addClass('x-status-text-panel').createChild({cls:'spacer'});

8:
9: //Kick off the clock timer that updates the clock el every second:
10:
//Would need to be set in application format
11:
Ext.TaskMgr.start({

12: run: function(){
13: Ext.fly(clock.getEl()).update(new Date().format('g:i:s A'));

14: },
15: interval: 1000
16: });

17: },
18: delay: 100
19: }
20: }



Here we can stop when then rendering is activated to investigate code execution further.

The debugger statment works in most browsers, i.e. Firefox with Firebug, IE 8, Chrome. In IE you will have to explicitly put the browser in debugging mode by clicking the "Start Debugging" button in the developer tools.

Happy Debugging,
B.

Saturday, November 20, 2010

XJS: Avoiding of Anonymous Functions Example

One of the difficulties one faces quickly using the ExtJS framework is the code organization. Any project quickly grows into a jungle of anonymous functions and heavily nested configuration objects. Hard to read and hard to maintain.
Examples commonly start simple but as soon as more elements are added they turn off newbies. A configuration object spanning multiple screens is not easy to digest, but this is how most online examples are presented. This, according to my informal survey, discourages new developers from proceeding.
This, in my opinion, is one of the greater roadblocks to learning the framework and making scalable ExtJS apps. I understand that changes in ExtJS 4 will introduce a more mature MVC based application framework; however, the examples I have seen are still heavily reliant on multi-level nesting and anonymous functions.
It is of course, a matter of preference, but I do find organizing code written in that fashion harder to read and manage long term.
For once, common mistakes, such as missing a semicolon, comma, or bracket closure, result in disproportionate debugging time. On the other hand, having multiple team members working in their own "sandbox" is hard to do if everyone is trying to change the same file.
Thus, I was looking for alternate organization but could not find a simple example to show that another approach was possible.

Take this common ExtJS code as example (this is a fairly simple example in ExtJS realm). It draws a border layout based viewport:


Ext.onReady(function(){
new Ext.Viewport({

layout: 'border',
items: [{
region: 'north',

html: '<h1 class="x-panel-header">Page Title</h1>',
autoHeight: true,

border: false,
margins: '0 0 5 0'
}, {

region: 'west',
collapsible: true,
title: 'Navigation',

width: 200
// the west region might typically utilize a TreePanel or a Panel with Accordion layout
}, {
region: 'south',

title: 'Title for South Panel',
collapsible: true,
html: 'Information goes here',

id: 'southPanel',
split: true,
height: 100,

minHeight: 100
}, {
region: 'east',

title: 'Title for the Grid Panel',
collapsible: true,
split: true,

width: 200,
xtype: 'box'
// more nested code could be added here, e.g a GridPanel

}, {
region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title

items: {
title: 'Default Tab',
html: 'Tab conent'
}
}]
});
});'


The formatting is nicely done, but still requires some getting used to. Only a few nested elements in this one yet the complexity can be already seen. What if you had a team of developers each working on one of the panels?

I prefer a more verbose but easier maintainable format that achieves the same result while allowing easier developer task separation (the use of multiple script tag is optional, I wanted to show a sense of separation of code):



<script type="text/javascript">
//we define a namespace to use for organization. This is optional.
Ext.namespace('startup');
</script>

<!-- panel definitions could be in another file -->
<script type="text/javascript">
// each panel could be seperate script file maintained by seperate developer or dynamically included via

// app server such as PHP / Railo / etc.
startup.northpanel = {
region: 'north',

html: '<h1 class="x-panel-header">Page Title</h1>',
autoHeight: true,

border: false,
margins: '0 0 5 0'
};


startup.westpanel = {
region: 'west',
collapsible: true,

title: 'Navigation',
width: 200
};

startup.southpanel = {

region: 'south',
title: 'Title for South Panel',
collapsible: true,

html: 'Information goes here',
id: 'southPanel',
split: true,

height: 100,
minHeight: 100
};


startup.centerpanel = {
region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title

items: {
title: 'Default Tab',
html: 'Tab Conent.'

}
};

//assemble panels here into array, alternatly this array could be the items definition
startup.aItems = [startup.northpanel,startup.westpanel,startup.southpanel,startup.centerpanel];

</script>

<script type="text/javascript">
startup.DoInit = function () {

//create view port
var bport = new Ext.Viewport({
layout: 'border',

items: startup.aItems
});
}
</script>


<script type="text/javascript">
//the actual ExtJS onReady function remains very small
Ext.onReady(function(){
startup.DoInit();

}); //end onReady
</script>


Of course, there is the element of preference and argument about throw away functions, e.g. only run once; I would still prefer good naming and definition as this is the long run makes my life easier.

Feel free to comment.

Cheers,
-B

Tuesday, November 16, 2010

XJS: Sencha 2010 con impressions

I am attenting the Sencha (formerly ExtJS) developer conference to learn about the future. Overall good energy at this conference. Definite feel of excitement about product and company from the developer community. Here are some early impressions:
  • Lots of activity since the company got funding
  • Company is trying to grow up and it shows: products are beeing build out, revenue model is being decided on / experimented with, business processes look raw around the edges. Overall this puppy is growing up.
  • Sencha has many projects in the cooking pot with some very innovative ones in the mix while still putting good improvements into the existing ones. The question will be, is the company going to be able to pull all this off or are they overloaded. Deliveries could slip, quality could suffer etc.
  • Their bread and butter ExtJS 4 is getting a dose of good overwhaul inlcluding things I have been griping about for a while. The main thing for me is that a best practices application structure is now supported out of the box, so you can finally organize your code for larger apps in a meaningfull way. (Yeah!!!) . My impression is that there are still some challenges to overcome with backward compatibility which they are working on. Many more good things of course, hope they can pull it off.
  • The developer interest is increasing, 3 x the number of developers attended this year.
  • Keynote from at&t cto John Donovan (he loves all phones and all people, yeah very politically correct answers all the way). The nugget from him was the statement that HTML5 is a viable application plattform and mobile apps will be written in it more the future and at&t will support it on many devices with native device library connections. If you believe this, the future of Flash and Flex would look limited. Another conference attendee said "Adobe is the dead man walking". Wow!
  • The Sensha touch platform for mobile apps is going to be free. Cool.
  • Common Annoyance: "It works in webkit" myopia. Understandably browsers supporting HTML5 are cooler from developer perspective but many examples given did not work or broke when another browser was used (Firefox, IE). This is poor for any platform claiming universal compatibility. Hopefully this will improve next year.


Cheers,
-B

Thursday, September 30, 2010

CF: ORM EntityDelete without EntityLoad

I must admit I am not a fan of the EntityDelete() function. Its inability to handle multiple records always nagged me. I know I can allways go back to CFQUERY or use ormexecutequery(). But what nagged me the most appeared to be the need to do an EntityLoad before I could remove the entity/record. This could potentially introduce unneeded database reads and latency.
e.g.:
myBook = EntityLoad("Book", 100, true);
EntityDelete(myBook);


Well it turnes out that the use of EntityLoad is not required. A colleague suggested I try the following instead which would eliminate the load operation, and since I thought that was pretty neat I am sharing ;o)

mybook = new Book();
mybook.setBOOKID(100);
EntityDelete(mybook);

In this fashion, you are creating the object reference in memory and guaranteeing that there is only one DB interaction at DELETE.

Cheers,
Bilal

Sunday, July 25, 2010

VS2010: Visual Studio 2010 - finding web reference option when working with Windows Forms Applications

Something I ran into today made me do a double take. This could have originated from the initial configuration choice I made when setting up Visual Studio 2010 or the tool is trying to be so smart it starts to get confusing..


However it happened, it does seem to make things more difficult when trying to create windows form applications. In particular, if you want to use a web-reference in your regular windows application the number of clicks has increased and discoverability has decreased.

Adding web-references to consume web services in ASP.NET application is not impacted by this change. In particular the context sensitive links to add web-reference are gone when I am in the Solution Explorer working on a Windows Form Application.






Instead the only thing you can seemingly do is to add a service reference. Though you can start here, web services that are registered through this channel do not behave at all like the previous releases of Visual Studio. Thus, beware, this is not what you want to do if you want to consume a regular web service, especially ones that are not created with VS to begin with. To get to the plain Jane adding of a web service you have to walk through some additional steps.

A) Select the "Add Service Reference..." option, then, click on the "Advanced..." button.





B) Click on the "Add Web Service" button from the advanced screen:




Allright that should do it to bring you back into the old web service ways.

Cheers,

B

Saturday, July 17, 2010

CF: The varExists() function -- Expanding IsDefined() to work with regular array and associative array notations.

Many times while working in ColdFusion code I am encountering the simple need to check for the existence of an index in an array, e.g. myArray[3]. While other languages may have had easier checks on this, in Adobe ColdFusion, I unfortunately, have to work around this scenario with many lines of code or different functions to call. Thus, I am able to construct fully well formed variable references and use them, but cannot check their validity in a simple fashion.

For example, I can't do a simple call to a universal function such as IsDefined("myVar[3]"). In this simple scenario we could have used ArrayIsDefined(), however, the scenarios I normally deal with are not so simple. In my scenarios I am not sure about whether "myVar" is an array in the first place or whether the index is numeric. E.g. I may need to check myVar[checkIndex]; this maybe a strucure with an associative array notation which takes me back to square one. Along these lines, multi-dimensional arrays such as myArray[3][4] are equally unqualified for ArrayIsDefined().

Similarly associative array notations that can be used with structures, e.g. myStruct["testNode"], equally do poorly on these checks and could require some sort of special checking and more lines of code.

How about a combination of things:
TestStruct.Animals['species'][1]['counts'][2]

All of these scenarios go beyond the ability of IsDefined() or other functions and cause more code to be written. Maybe this would be an opportunity to expand in future version of ColdFusion but for now we're stuck or are we? (yeah, rhetorical question this one).

I made this a test project and developed an alternative function, varExists(), to IsDefined(); it may not be usable in all scenarios but will come in handy in coding.
The sample implementation can be downloaded here (varExists.zip (3KB)).

The first objective was just to be able to handle the complex notation scenarios that commonly fail under IsDefined().

e.g.:
varExists("TestStruct.Animals['species'][1]['counts'][2]") should operate without a hitch on complex variable notations. While at the same time maintaining full backward compatibility with IsDefined(). So you should be able to do things like this varExists(varName), varExists should check for the existince of the content referenced by the content of varName, e.g. a string such as "TestStruct.myArray[2][1]".

But, why stop there, the next thing that I commonly do once I check for the existence of a variable is to retrieve its value for some sort of operation, so I added this option as second argument. Thus, varExists will automatically return the value referenced as part of its operation if "True" is passed as second argument, e.g. varExists("myUserArray[33]",true). This would return the UserName at array index position 33.

Another common task I perform when the value is not known or "undefined" is to assume a default value. Thus, I added this as third parameter. When a third parameter is supplied it will be returned, when the actual variable reference is undefined.
For example:
varExists("myUserArray[33]",true,"John Doe")
would return "John Doe" if the array index 33 is not populated for some reason.

The example code has the test array and unit tests with sample scenarios. The hope is that eventually the ColdFusion language can accommodate these type of operations natively.

Happy experimenting.

Cheers,

B.

Addition:

The Railo CFML engine does not exhibit the flaw outlined in this article. Thus, if you use Railo, you probably will not encounter scenarios in which you can construct a valid variable reference but cannot check for its existence. The IsDefined() function works as expected, however, if you want the expanded functionality of retrieving variable values etc. you would still need to use the varExists() User Defined Function (UDF) provided here.

Best,

B.

Tuesday, June 1, 2010

CF: Connecting 64-bit Coldfusion to 32-bit MS Access databases

First off, don't ask me why you would want to do this, just go with the flow.
In other words, let's not get bogged down on how you should not put anything on Microsoft Access anyway and accept the fact that there is still many applications that are perfectly happy with it ;o)
The problem has existed for a while but it dawned on me more clearly as I was sitting in on a hands-on beginner CF class at NC Dev Con and several of the participants immediately ran into this with their brand spanking new, high powered, Windows 7 64-bit computers.

So it seems more common that you would want to take the 64-bit edition from Adobe for a spin. But as soon as you attempt to connect to anything 32 bit you receive non-descriptive errors such as:

"Unable to update the NT registry. Variable DRIVERPATH is undefined."

Maybe dropping those options from the list of available drivers would have been wiser and less frustrating for users. Something for Adobe to ponder about I guess.




Microsoft does not have any (as of this writing at least) ODBC drivers for 64-bit Microsoft Access; in general, not much ODBC activity in a long time from the Microsoft camp. So, you might be well able to load up Office 2010 in 64 bit format; using the resulting databases for your projects, however, is a fairly complicated tasks.

As with all workarounds there are many steps to complete, so here we go:

1.) Download and Install 64 bit SQL Server 2005 Express Edition. You cannot use SQL Server 2008 Express edition, so don't try. It is lacking the needed OLE DB Provider.

2.) Download and Install Management Tools

3.) Download and Install Microsoft SQL Server JDBC drivers

For steps 1 through 3 here is a nice tutorial by Steve Brownlee - Fusioncube

4. ) Copy your MDB somewhere, e.g. c:\temp

5.) Created Linked Databases using Microsoft Jet 4.0 OLE DB Provider

a) Linked Server Menu. Right click on the Linked server node and then click on "New Linked Server..." sub-menu option:



b)linked server dialog. Product name can be anything you like. Data source should point to your access file:





6.) Create DS in CF Admin

a) create type other


b) specify data source connection properties




7.) Create sample code for CF. Your query code has to be changed, so you might want to create a variable to hold your prefix to your tables in case you change from 64 bit to 32 bit and vice versa.

Note that you have to use the four part syntax to query out of a linked MS Access to SQL database. You are just omitting two parts, there is also another syntax possible : Openquery(Linked_Server, 'Query') which I will not dig into.



To specify a query table in your access database you start with the name you have entered in SQL Server while the creating the link. In my case this is "Northwind". This name is followed by three periods (...) and, then, by the actual table name:
e.g. : NORTHWIND...EMPLOYEES

Here is my example code:
HelloNW.cfm file:



<cfquery name="selNorthwindEE" datasource="Northwind">

SELECT *
FROM NORTHWIND...EMPLOYEES

</cfquery>

<cfdump var="#selNorthwindEE#">



8.) Enjoy





Cheers,
B.

Monday, May 17, 2010

CF:Flex: FOF: Flex on Fusion, thoughts on what it takes to create a unified framework

The Situation

If you have worked on either Flex or ColdFusion you know that nowadays there is more development frameworks than people know what to do with.
At one point having a consistent pre-defined path to application development on either of these platforms meant you had to invent wheels many times over. Now, the situation has changed to one where you attempting to decide which framework to use; long discussions and passions are aroused.
At some level this has become as counter-productive as the use of no framework was before.
Here are the commonalities I noticed:

a) Frameworks are for developers:

You have to learn the platform, learn the framework and have some sort of knack for writing code.

b) Frameworks only cover one or the other technology.

They do not span technologies, even if your application is expected to. Thus if you have to write an app that uses a ColdFusion back-end and a Flex front-end; you have to put the puzzle together yourself. One may even say we are back where we were several years in the no framework days.

I understand, there are wizards to get you started in both directions, e.g. CF wizards for flex, and flex wizards for CF, but a wizard a framework does not make ;o)

Don't get me wrong. There are some cool things being done with scaffolding to generate fully fleshed out UIs that are generated from a database, a la Ruby. For example, check out Apptacular.

c) Frameworks focus on developer application parts

Frameworks focus on allowing programmers a base structure that can expanded. Most of this centers around the use of the MVC pattern in one form or the other. However, less attention is given on other services needed in order make an application complete or usable.

For example commonly left to the programmers are things like internationalization, user management, rights management, currency and data management, skinning management.


The Thought

Using frameworks either on ColdFusion or Flex is nothing new. Creating a Framework that spans both is. Thus the idea of Flex on Fusion (FoF) came into my head and just would not let go. I thought, well, now what? Do you really want to create yet another framework even if the idea sounds cool. Who would want to learn it? and Why?
But, for some reason, the idea was persistent and would not easily go away by itself.
More thinking occurred and I do think that this framework has to enable the user (not necessarily a developer) to quickly built full applications. More like the Magic environment, more graphical, less focus on writing code.
And so I am putting it out here to gather feedback and expand on it.

The idea is not to obsolete all other frameworks, rather build a more user centric framework that can be used along with other frameworks. Thus, you should be able to use platform level frameworks to construct sub-pieces. Use the stength of each plattform, CF, for the database and logic, Flex, for advanced visualation and UI, in a combined stronger form.

I am envisioning a startup process that walks the user through the basic steps, e.g. pointing at the database and determining a subdirectory to write the model implementation, etc. This is similar to other scaffolding models; however, the application that is built will also have a user and security model. More importantly, after the basic build is finished, there should be a UI that can be used to define the application further without coding. Adding more data/screens should all be doable via UI. In the extreme thought the UI would expose an IDE for the pieces that require coding.

Once an application is generated, it can extended easily be extended while it is running by users with sufficient permissions.

I will post some more detail describing screens and workflow in a bit.

Cheers,
B.

Thursday, April 15, 2010

Java: VisualVM "Add JMX Connection..." missing from file menu

A quick note as I had not seen this before.
This occurred to me on windows 2008 R2 server platform.
I looked and even compared log files among computers could not find anything conclusive that would cause this. But for some reason the option to add a JMX Connection was not available any longer in VisualVM tool.
Not in context menu and not in File menu.

Much trial and error followed but the solution was to redo the installation.
Thus, the only thing that worked is to delete the VisualVM directory, re extract the zip files to a different directory, then start the VisualVM exe with Administrative privileges.
After the initial calibration, the Menu item for JMX Connection was available again.

Yohoo!
-B

CF: Java: Using free VisualVM tool to monitor running ColdFusion Servers

You may have had a chance to use the VisualVM tools in the past and found them helpful to get an idea on what is actually happening on the VM while your code is running.






The VisualVM tools can help you detect memory leaks in progress as well as other constraints on your server before it crashes. But even after a crash these tools are helpful. The tools are very graphical and easier to use than attempting to read thread dumps and heap dumps manually.

Here are some simple steps to use this great tool set with ColdFusion.


1) download java jdk 1.6.09 or later
http://java.sun.com/javase/downloads/index.jsp

2) Download Visual VM
https://visualvm.dev.java.net/

3) Configure Coldfusion jmx access
Best way is to go to Coldfusion Administrator Java and JVM settings section.
Add the following parameters:

-Dcom.sun.management.jmxremote.port=8701
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false



You can decide whether to use ssl or not, and also on the port to use. If you want to use jmx authentication I would recommend you read:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html#gdenl


4) Configure your Visual vm start up to point to your jdk if you have not set environmental variables:
e.g. on Windows
if you extracted the visualvm files into C:\Java\visualvm_122
and
Your JDK is located in C:\Java\jdk1.6.0_19
then you can use the following command line:

C:\Java\visualvm_122\bin\visualvm.exe --jdkhome "C:\Java\jdk1.6.0_19"

I put it in a batch file that I can start easily.

5) Start up the VisualVM tool (it may have to go through calibration first, simply acknowledge), then, and establish a connection a JMX connection by right clicking on the local node and choosing "Add JMX Connection..."




6) Add connection parameters



Now you should be able monitor your server as it runs. I found this to be more stable than the Server Monitor in Enterprise versions of ColdFusion especially under load. It does not have all the same information but you can get a detailed breakdown of VM memory use.

To get into the details of which CF code is using memory you have to generate a heap dump and use the heap walker to run the analysis. All the classes starting with cf... are your code running on the VM.






You also have the option to monitor remote ColdFusion servers as well. You monitor multiple remote and local CF instances in one console, however, unlike the local monitoring, you cannot generate a heap dump when using remote connections.

Creating a remote connection involves two steps in VisualVM after you enabled jmx access on ColdFusion.

a) Adding a remote host. You do that by right clicking on the "Remote" node in VisualVM



b) Specify the host name and display name and connection jstatd port (this is the same port you set in your CF JVM start up parameters). You will need to use the Advanced Settings dialog to do this. The port should be the same you set in the ColdFusion Java and JVM settings for that instance of CF.



c) Set up a remote JMX connection by right clicking on the server name node and choosing "Add JMX Connection...". This will bring up a similar window as in step 6 above. Fill in the server and port information and you should be able to see your server.


Another common use for the VisualVM tool is analyse a Heap Dump after a VM crashes due to memory problems. You can open and walk through the final VM Heap state. To make ColdFusion produce a heap dump you will have to change the jrun.config file and add this config option:

-XX:+HeapDumpOnOutOfMemoryError
If there is a crash the heap dump should be a text file located in your {coldfusion}\bin folder.

More information on how to use the VisualVM tool is available on the VisualVM website; definitely worth a look.

Cheers,

-B.

Tuesday, March 16, 2010

CF: Dynamically changing Application.cfc using server specific configuration files

This started as I was reading an old post from Ben Nadel.
I did see that Ben was using a methodology to set up Application startup parameters in a special config function and commented on it.
I wrote about our experience with externalizing these parameters into specific configuration files instead and Ben stated that copying could be a problem if you override the config files.
Here then is my thoughts on how to keep external xml files to describe application specific settings, e.g. production vs test vs datasource names, timeouts, etc.
Nothing new here right? But the goal is to be able to keep the configuration files without a headache and conflicts.
Lets take a sample set of parameters in a file like so:

<wddxPacket version='1.0'>

<header/>

<data>

<struct>

<var name='REQUESTERRORHANDLER'>



<string>RequestErr.cfm</string>

</var>

<var name='VALIDATIONERRORHANDLER'>

<string>ValidationErr.cfm</string>



</var>

<var name='EnableErrorHandlers'>

<string>No</string>



</var>

<var name='DEBUG'>

<string>No</string>

</var>



<var name='ADMINEMAIL'>

<string>change_please@mycompany.com</string>

</var>

<var name='DATASOURCE'>



<string>APPDS</string>

</var>

<var name='APPLICATIONNAME'>

<string>StandardName</string>



</var>

</struct>

</data>

</wddxPacket>



The trick here is to be able to have a system which allows you to keep different configuration files without fear of overwriting them; and, even if you do copy over them by accident (or even if you have many different ones), the system will be smart enough to pick the correct one.

My implementation (Application.cfc) for this looks like this:



<cfcomponent>
<cfscript>
//start off by reading config file, read contents into this.stcConfig
initConfig();
//set application options from config file
this.Name=this.stcConfig.ApplicationName;
this.SessionManagement=
"Yes";
this.SessionTimeout=this.ConfigTimeout;
//other application parameters can be set
</cfscript>



<cffunction name="onApplicationStart" output="No">
<!--- no need to lock app scope variables in this function unless called from
another function --->


<!--- now make the config file data available to the application scope (bsoylu 03-17-2010) --->
<cfset Application.stcConfig = this.stcConfig>

<cfset Application.ConfigFile = this.ConfigFile>

<!--- we are setting some dynamic Error Handlers --->
<cfif IsDefined("this.stcConfig.EnableErrorHandlers") and this.stcconfig.EnableErrorHandlers>

<cferror type="REQUEST" template="#this.stcConfig.REQUESTERRORHANDLER#" mailto="#this.stcConfig.AdminEMail#">
<cferror type="VALIDATION" template="#this.stcConfig.VALIDATIONERRORHANDLER#" mailto="#this.stcConfig.AdminEMail#">
</cfif>

<!--- do other stuff now ...--->


</cffunction>


<cffunction name="OnRequestStart" >
<cfargument name="CallPage" type="string" hint="This is the page the user is calling. This argument is populated by CF automatically.">

<!--- do your request work --->

</cffunction>


<cffunction name="OnRequestEnd">
<!--- finish up your request code goes here --->

</cffunction>



<cffunction name="getIP" returntype="string" access="private" hint="return server main IP address">
<cfscript>
//get Inet Address type object from JVM

var objInetAddr = createObject("java", "java.net.InetAddress").getLocalHost();
return objInetAddr.getHostAddress();
</cfscript>
</cffunction>

<cffunction name="initConfig" access="private" output="Yes" hint="load config file">

<cftry>
<!--- first check for server specific config file config.XXX.XXX.XXX.XXX.xml, e.g. config.196.18.12.78.xml --->
<cfset strConfigFile = getDirectoryFromPath(getCurrentTemplatePath()) & "config.#getIP()#.xml">

<cfif not FileExists(strConfigFile)>
<!--- fall back to global config file --->
<cfset strConfigFile = getDirectoryFromPath(getCurrentTemplatePath()) & "config.xml">
</cfif>

<cfif FileExists(strConfigFile)>

<cffile action="READ" file="#strConfigFile#" variable="strConfigWDDX">
<cfif iswddx(strConfigWDDX)>

<cfwddx action="WDDX2CFML" input="#Trim(strConfigWDDX)#" output="this.stcConfig">
<!--- save the config file that we use --->
<cfset this.ConfigFile = strConfigFile>
<cfelse>

<cfthrow type="INIT" detail="Incorrect Configuration File. No WDDX detected.">
</cfif>
<cfelse>
<cfthrow type="INIT" detail="Missing Configuration File. No global or server [#getIP()#] specific configuration file found.">

</cfif>

<!--- prepare timeouts --->
<cfif IsDefined("this.stcConfig.SessionTimeOutMinutes") and Val(this.stcConfig.SessionTimeOutMinutes) GT 0>

<cfset this.ConfigTimeout = CreateTimeSpan(0,0,Val(this.stcConfig.SessionTimeOutMinutes),0)>

<cfelse>
<cfset this.ConfigTimeout = CreateTimeSpan(0,0,20,0)>

</cfif>

<cfcatch type="Any">
<cfoutput>#cfcatch.detail#</cfoutput>
<cfabort>
</cfcatch>
</cftry>
</cffunction>

</cfcomponent>


The idea here that the Application.cfc selectivly loads configuration files. It looks for a server specific configuration file, e.g. config.10.10.1.100.xml , then a global configuration file, e.g. config.xml.
Allmost all of the important work occurs in the initConfig() function. It determines the machine's IP address then alternatly looks for a machine specific configuration file, followed by a global configuration file. If neither can be found, we throw an error.

Thus, even if I copied my development server's configuration file by accident to the production server it would not be of consequence for the production server. I am of course subject to the normal human errors. If I delete all configuration files I am hosed anyway etc.

Try it out and let me know if this helps.

Cheers,
-Bilal

Thursday, January 28, 2010

CF: Flex: PGP Implementation for ColdFusion

Pretty Good Privacy (PGP) is a computer program that provides cryptographic privacy and authentication.
PGP is often used for signing, encrypting and decrypting e-mails to increase the security of e-mail communications. It was created by Philip Zimmermann in 1991.

The use of PGP in file exchanges has increased over the years and has become a common way of securing file contents. Thus, encountering this in more and varied projects is not unusual.

There are several implementations for popular platforms such as Java and .net; I classified them into brought camps of heavy commercial, or hard to use open source; thus the availability of easy to
implement PGP solutions for ColdFusions is limited. In particular, I found existing implementation rather difficult to use.
Thus, I embarked on this project. To make a long story short, I ended up using the underlying work of the
league of bouncy castle folks. The complete source code for those libraries can be downloaded from there.

I implemented the most common scenarios (generate keys or key rings, encrypt and decrypt) and exposed all this through a ColdFusion component to the world. Thus the effort to use of PGP is reduced to one liners of code (which I like).

Along the same lines, if you use Flex and needed a library to encrypt/decrypt this implementation can easily used as backend for that kind of scenario. A few tweaks to the main component should allow you to call on all the functions, read, write, generate keys etc.

Of course, there is so much more that can be done with PGP. Time permitting I may expand this implementation to expose other functionality.

You can download this from RIAForge (pgp.riaforge.com).

Cheers,
-Bilal

Thursday, January 7, 2010

CF: Connecting ColdFusion to Microsoft Azure SQL

I am impressed by what Microsoft has been able to create with the Azure platform. The more I play with it the more I like it. What impresses me most is how simple it is to get going (I am comparing with Amazon). The big caveat here is that you use MS technologies. If so, Azure should be on the short list for evaluation.
However, and, here I go again reversing myself, if you want to connect a ColdFusion front end to a Microsoft Azure SQL back end, things are a little more quirky. Please don't ask why you would do such a thing, just stay with me in that it is highly cool ;o)

First, you should evaluate whether your application will give to this kind of setup. On the ColdFusion side you should have good control on the amount of data you exchange with the database(pagination and other techniques); you also should have some tolerance for higher latency; there is delay in the round trip to get data from Microsoft etc.

Of course the usual evaluation of whether you are ok with hosting data in the cloud should take place. But on the other hand, taking this for a spin is easy enough.

In my setup I am hosting the CF server on my laptop and MS is supplying the database.

1) Learn about Azure: Learn about Azure things and then Create Account

2) Create your first database instance online using your browser

3) Get your tools. You do not need to download the Visual Studio or other SDKs to work with SQL Azure, but you will need to use the SQL Server 2008 R2 Management tools. Currently only available as CTP edition.

4) Optional: Migrate some data. For me, using the script wizard in the Management Studio worked the best. You can switch it to produce SQL Azure specific scripts, but you still have to tweak them. Your primary keys have to be clustered when creating tables.
e.g.:

CREATE TABLE [dbo].[TestTable](
[Test_ID] [int] NOT NULL,
[TestName] [nvarchar](50) NOT NULL,
[TimeZoneOffsetHours] [smallint] NULL,
[TimeZoneOffsetMins] [smallint] NULL,
CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED (
[Test_ID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)



5) Once you have some data we start with the ColdFusion parts. I have not been able to use the Adobe supplied drivers. I had to download the Microsoft JDBC 2.0 drivers. When you extract the jdbc drivers there are two .jar files. For CF you will need to use [sqljdbc4.jar]. Copy this driver into [cfroot]\lib folder.

6) Restart ColdFusion

7) Configuring your Data Source in the ColdFusion administrator. Here it gets a little complicated. You need to create a data source of type "other". Also, you cannot use the connect strings that are supplied by MS directly, though pieces are useful. The current stance is that Microsoft does not support JDBC connection but if you can work it they are fine with it. To make it simple I am attaching an image: (please note the way in which we have to set the User name)(replace myID with the database User ID and myServer with your server name from Azure):



8) Configure your connection settings. The Azure platform will drop your connection frequently. So maintaining connection is not really an option. This is what worked best for me to make it appear as if we had no connection issues.



Ok, hopefully this all worked out for you and you can take this for a spin.

Cheers,
Bilal