Check out our new training course on AngularJS for Flex Developers

Manually configuring ColdFusion with IIS7

I sent this email out yesterday as part of the Flextras/DotComIt newsletter. I thought I'd repost it here.

I recently had the opportunity to move some of my hosted sites to Amazon web services. The Flextras site, The Flex Show, and my personal blog, are now all hosted on EC2. It has been a few years since I've had to deal with my own production server maintenance; and I came across a weird issue with IIS7 and ColdFusion 9. I thought I'd describe the issue and explain my solution.

IIS6 Compatibility is turned on

Normally, when you create a new instance of an IIS web server, you'll need to associate ColdFusion with it. ColdFusion provides a tool named the Web Server Configuration Tool that can attach an instance of ColdFusion with an instance of IIS. If you happen to be using ColdFusion 9.02--or later--and IIS7; you may receive this error:

The Web Server Configuration Tool will not work with IIS7 if IIS6 Management Compatibility is enabled. On this particular server, the management compatibility was enabled for the FTP plugin could be managed on the server. I did not want to uninstall the IIS management compatibility if I could avoid it. How could I tell IIS7 that it should send .cfm requests to ColdFusion for processing without using the Web Server Configuration Tool?

Editing the applicationHost.config file

Under the hood the mappings that tell IIS7 how to communicate with ColdFusion are in a file named applicationHost.config. You can find this file in the 'C:\Windows\System32\inetsrv\config\' directory. This file contains a lot of configuration for IIS7.

If IIS7 was already installed when ColdFusion was initially installed, then you can find a section that references an existing IIS7 instance with your existing ColdFusion instance. Look for something like this:


<location path="iisInstanceName">
<system.webServer>
<handlers>
<clear />
<add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
<add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
<add name="AboMapperCustom-130401" path="*" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" requireAccess="None" responseBufferLimit="0" />
<add name="AboMapperCustom-130411" path="*.jsp" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130412" path="*.jws" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130413" path="*.cfm" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130414" path="*.cfml" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130415" path="*.cfc" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130416" path="*.cfr" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130417" path="*.cfswf" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130418" path="*.hbmxml" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="AboMapperCustom-130419" path="*.hbmxml" verb="*" modules="IsapiModule" scriptProcessor="C:\ColdFusion9\runtime\lib\wsconfig\jrun_iis6.dll" requireAccess="Script" responseBufferLimit="0" />
<add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" />
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
</system.webServer>
</location>

If you're using CF Standard, you can just copy and paste this section; then change the path name on the location to be the name of your new IIS7 server instance. Restart your IIS instance and that should be all you need. Otherwise, you'll have to create the above section manually; by copying and pasting from above and changing your paths to relate to your own CF Install.

Although I didn't have the experience of setting this up using CF Enterprise, I expect the procedure will be similar; you'll just need to point to the jrun_iis6.dll for your specific instance of ColdFusion.

How to Create a System for Caching Data

I wrote this article for the monthly Flextras newsletter, and thought I'd share it here.

I was working with a client recently and we had some performance problems while accessing remote data from within our application. The user interface, built with Flex, was accessing our ColdFusion server, and ColdFusion would relay requests onto another remote system using SOAP web services. The web service data didn't need constant updates, so we decided to create a caching system for the data to improve performance. I thought the concepts behind that would make an interesting topic for this month's newsletter.

What Type of Data to Store?

We decided it was best to create a generic system to cache any type of data. The system should handle any type of data we wanted to throw at it. To accomplish this, I created two classes a CacheManager class and CacheData class. The CacheData class is intended to be a generic object used by the CacheManager. Here is a diagram of the class:

The CacheData class is used by CacheManager to store the cached data. It has three properties: the data to store and two dates. The first date is, dateCached, which keeps track of the date and time that the data was first cached. The second element is dateLastAccessed, which keeps track of the date that the data was last accessed. The data property should be protected, or private, or something similar depending upon your language of choice. The two date properties should be publicly accessible.

The class has two methods: get() and set(). The get method returns the data and should also update the last accessed date value to the current date and time. The set method will update the internal data property, as well reset the two dates. In an attempt to keep this as platform agnostic as possible; this would be pseudo code for the class:


package{ class CacheData{
// this value stores the data
protected var data : *;
// this value stores the date that the data was initially stored
public var dateCached:Date
// this value stores the date that the value was last accessed
public var dateLastAccessed:Date
// this method can be used to retrieve the data
public function get ():*{
dateLastAccessed = getCurrentDate();
return data;
}
// this method can be used to set the data
public function set(value:*):void{
data = value;
dateCached = getCurrentDate();
dateLastAccessed = getCurrentDate();
} } }

This is a very simple class, not much more than a glorified value object.

The CacheManager Class

The CacheManager class is a bit more complicated. This is your application's window into the cached data.

This is the class diagram for the CacheManager:

The CacheManager has two properties; minutesCached and cachedData. The minutesCached property is an internal value will be used to determine when data should be flushed and deleted. The cachedData is also an internal value, but it is a bit more complicated. I created that as an associative array of associative arrays. In Flex, an associative Array would be a Dictionary; in ColdFusion that would be a Struct. The first key of the associative array is the type of data you want to store. I call this the cacheKey. This may be "products" or "orders" or something similar, depending on the data you want to store. The second associative array's key is the dataKey. Examples of this may be "ProductID1" or "Order13" or anything that can be used to uniquely identify the type of data, such as its database's Primary Key.

The combination of the dataKey and the cacheKey is used to retrieve the data. The use of the two key structure allows a single instance of the CacheManager to be used to cache multiple types of data. There are also two methods as part of the cacheManager: store() and retrieve(). The store method accepts three arguments: the data, the cacheKey, and the dataKey. It will create a new object of CacheData object and call the CacheData.set method to store the data. It is the simpler of the two methods.

The retrieve method is where the magic happens. It first check's to verify that the data exists. Then it checks to make sure that the data is still relevant based on the current date and the date that the data was last accessed. If the data is too old; then it can be deleted. Otherwise it can be returned. This is a pseudo code class:


package{ class CacheManager{
// this value specifies how many minutes the data should be cached
protected var minutesCached : int = 1440;
// this value contains the cached data; using a two key structure. A CacheKey and a DataKey.
protected var cachedData:Dictionary = new Dictionary();
// this method can be used to retrieve the data
public function store (data:*, cacheKey:String,dataKey:String):void{
if(!cachedData[cacheKey]){
cachedData[cacheKey] = new Dictionary();
}
cachedData[cacheKey][dataKey] = new CacheData();
cachedData[cacheKey][dataKey].set(data);
return data;
}
// this method can be used to set the data
public function retrieve(cacheKey:String,dataKey:String):*{
var cacheObject = cachedData[cacheKey][dataKey]
if(!cacheObject){ return; }
var dateToClearCache :Date = getCurrentDate() - minutesCached
if(cacheObject.dateLastAccessed <= dateToClearCache){
cachedData[cacheKey][dataKey] = null; return;
} Return cacheObject;
} } }

Although it is beyond the scope of this article, you could also create a method to automatically clear old cache data. This is probably more memory efficient than waiting until the data is retrieved to clear it out.

Putting it All Together

Now that we have the code behind our CacheManager, the last step is to put that to use. First, create an instance of it; presumably in some globally accessible variable.


public var cacheManager :CacheManager = new CacheManager();

Let's say you just loaded a bunch of products from some remote source. You'd loop over them and store them in the CacheManager instance:


For each product in productArray
cacheManager.store (product, 'products',product.id):
End For Loop

In this code, we use the cacheKey named products and use a product ID for the dataKey. I once read something that said you when you file something; you want to make sure to file it in the way that you can find it when you need it. The dataKey for your cache should follow the same suit. When you need to retrieve the data, you want it to be filed under some name that you can use to retrieve the data later.

Retrieve the data from the cache when you need it, like this:


var product : Product = cacheManager.retrieve('products',product.id);

Be sure to check that you actually got a product back from the cache before you try to use it:


If(!product){
// do something to retrieve the product data from source
// or make sure your code accommodates for a non-existent product
}
// process product

Final Thoughts

I hope you found this article interesting. I did my best to make this as conceptual as possible, so you may have to modify the code in order to work in the language of your choice.

I have two other mini-announcements that I added to the recent Flextras Newsletter. First, the code that never became the Flextras Flex Spreadsheet Component has been open sourced by the original author. It is a very impressive piece of technology. Second, if you're in the mood for interesting weird music; I recorded a full album worth of songs for February Album Writing Month. It is a nice little diversion from programming at times.

Flash Remoting won't connect "NetConnection.Call.Failed"

I've been doing some with for the Flextras promotions around 360|Flex. As part of the promotions I am creating a customized version of my Game; strictly for Flextras. It is going to allow people to login and will keep score on our server instead of internally to the app.

Since this is a Flash app; I'm using Flash Remoting to connect to our ColdFusion server. Everything worked fine on my local machine. Everything worked fine on my development server (AKA Staging). However, my production machine was giving errors that looked like this:

faultCode: "Client.Error.MessageSend"
faultDetail: "Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed: url:
faultString: "Send failed"

I've tried a lot of different things including not using http instead of https. I knew that Flash Remoting was working on the production server because I had other Flex apps working without problems. So, what was the problem?

I've been working on this on and off for about five days; so tried a lot of different things. In the end I discovered two things:

  1. Make sure your Flash Remoting URL has a '/' at the end of it. 'https://www.flextras.com/flex2gateway' was not working. It appeared to add a JSessionID on it; which was causing the server to throw a 404 error; causing the whole call to fail. However, if I changed this to 'https://www.flextras.com/flex2gateway/' that problem went away.
  2. Turn off the Flash Builder Network Monitor. The Flash Builder Network monitor was intercepting the call and causing it to fail. The calls appeared to work fine from a web browser with the Flash Builder Network Monitor enabled, but not from the mobile app.

I think--but am not completely sure--part of my issues related to using HTTPS on the server instead of HTTP. That could be the reason I had issues on the production server, but not my local or staging box.

Migrating Instances from ColdFusion 8 to ColdFusion 9

Unfortunately, I came back from lunch yesterday to find my laptop was dead. I couldn't get it to load. It was a refurb unit that had served me well enough for three years. I was hoping to get another 6 months out of it; but it is what it is.

This put me in the unfortunate position of needing to set up a new development machine **NOW**. Thankfully, I have a new machine here just waiting to be set up for development. It gives me a slight delay before I have to replace the laptop.

The old machine had CF8 installed in the multi-server mode. I had used the CF8 instance manager to deploy multiple CF8 and CF9 instances of ColdFusion for development purposes. Could I take those instances created in CF8 and somehow use them in CF9 without having to recreate them from scratch? Yes, the answer is yes.

I wrote a bit my experiences moving these same CF8 instances from one machine to another in the past. Here is how I did it:

  1. First I installed Apache. It is my preferred web server. Then I stopped Apache, backed up the config files, and replaced the 'clean' config files with my old config files. This will give me all the info that attaches Apache to the CF Instances and what not.
  2. Then I installed ColdFusion 9; the multi-server edition. During hte install I attached it to my 'clean' config of Apache. I had no idea, when I was doing it, if that was a good idea or not but it worked and the 'old' Apache config seemed to connect up to ColdFusion without any issues. So now I have a working CF Administrator with an instance manager.
  3. Then I used winmerge to compared my old CF8 install directory and the new CF9 install directory. I copied over all my server instances--except for the cfusion one that was created by default. The server instances are located in the servers directory of the install.
  4. Finally, I scoured over all the differences in the winmerge report to figure out how CF was deciding what was an instance and what wasn't. There are two files:
    • lib\wsconfig\wsconfig.properties
    • lib\servers.xml
    I believe these two files contain all the data for how the CF Instance manager finds the instances. I used winmerge to move all my "old" instances into the new files. I restarted the Macromedia JRun and Macromedia ColdFusion instances, reloaded the admin and all my old 'CF8' instances showed up. Just like magic.

Now all I have to do is create the Windows services for these instances--as I talk about in my other post. Since CF10 is not going to use JRun, I'm not sure I'll be so lucky during the next upgrade.

CF101 Archive: October 2007 Every Beginner must Grow Up

Disclaimer: In 2007, sys-con closed down the ColdFusion Developer's Journal, and I wanted to post all the articles I had written to this site. I started, but got distracted on other things. I'm performing a purge of my digital archives and found the articles. At this point they are posted here more for my own archival purposes than because anyone is longing to read them.

This article is being reposted in accordance to my contract with sys-con. I had them change the default contract so that I could post articles on my personal site.

This article was my final article. I'm not sure if it was ever published formally, though.

CF101 Archive: September 2007 Object Oriented Pizza

Disclaimer: In 2007, sys-con closed down the ColdFusion Developer's Journal, and I wanted to post all the articles I had written to this site. I started, but got distracted on other things. I'm performing a purge of my digital archives and found the articles. At this point they are posted here more for my own archival purposes than because anyone is longing to read them.

This article is being reposted in accordance to my contract with sys-con. I had them change the default contract so that I could post articles on my personal site.

This is without a doubt the favorite article I've ever written. I wrote it afraid I was going to become the active target for every high level CF Developer. That didn't happen thankfully. I remember the response being relatively positive.

CF101 Archive: February 2007 Data Table Gateways

Disclaimer: In 2007, sys-con closed down the ColdFusion Developer's Journal, and I wanted to post all the articles I had written to this site. I started, but got distracted on other things. I'm performing a purge of my digital archives and found the articles. At this point they are posted here more for my own archival purposes than because anyone is longing to read them.

This article is being reposted in accordance to my contract with sys-con. I had them change the default contract so that I could post articles on my personal site.

This article follows the design pattern scheme of the previous one and focuses on Data Table Gateways. An interesting tibbit is that I would rip my articles out of the PDFs and write up these entries while watching the TV Show supernatural. I bet I got out of the habit when the season ended which is why these articles remained unposted for so long.

CF101 Archive: January 2007 Data Access Objects

Disclaimer: In 2007, sys-con closed down the ColdFusion Developer's Journal, and I wanted to post all the articles I had written to this site. I started, but got distracted on other things. I'm performing a purge of my digital archives and found the articles. At this point they are posted here more for my own archival purposes than because anyone is longing to read them.

This article is being reposted in accordance to my contract with sys-con. I had them change the default contract so that I could post articles on my personal site.

In this article, I delved into some of the design patterns that a lot of ColdFusion developer's were starting to use, in this case data access objects. I don't have anything against design patterns but I often feel some of the proponents of design patterns pitch them as the answer to all your problems. In reality, they are just an approach to solve something and there is often a tradeoff for using one to solve a problem.

CF101 Archive: October 2006 Five Cool Things with ColdFusion

Disclaimer: In 2007, sys-con closed down the ColdFusion Developer's Journal, and I wanted to post all the articles I had written to this site. I started, but got distracted on other things. I'm performing a purge of my digital archives and found the articles. At this point they are posted here more for my own archival purposes than because anyone is longing to read them.

This article is being reposted in accordance to my contract with sys-con. I had them change the default contract so that I could post articles on my personal site.

This is one of my favorite articles; because I cover a lot of the cool things I had been doing in my own development, such as hooking CF up to a credit card scanner and a bar code scanner and generating bar codes. Around this time, CFDJ's publication schedule started to get more and more spotty. I didn't know for sure at the time, but it was probably starting to wind down. The publication world was starting to change, and magazines were not going to be the future.

CF101 Archive: September 2006 A first look at FusionDebug

Disclaimer: In 2007, sys-con closed down the ColdFusion Developer's Journal, and I wanted to post all the articles I had written to this site. I started, but got distracted on other things. I'm performing a purge of my digital archives and found the articles. At this point they are posted here more for my own archival purposes than because anyone is longing to read them.

This article is being reposted in accordance to my contract with sys-con. I had them change the default contract so that I could post articles on my personal site.

This article is a look at the third party ColdFusion command line debugger, FusionDebug. Debuggers like this are a fantastic tool for programmers. I loved it when working with technologies that pre-dated my work with CF and I loved it when working with Flex. For some reason, debuggers never took a final resting place in my CF Toolset.

More Entries

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.

pure garcinia cambogia

payday loans

seo services

seo services