AdobeStock_455007340

How Would You Implement Per Application Settings?

ColdFusion Administrator settings are server wide. And users have long asked for more granular settings, ideally per application. A thread on cf-talk today discussed per application mappings, but there is actually more to it than that. What about debug settings? Log file paths? Default SMTP server? There are lots of settings that are server-wide right now (unless you are running multiple instances, in which case they are instance wide).
So, if ColdFusion were to support per application settings (which, if present, would override the default CF Admin settings), how would you expect to define them?

  • tag attributes
  • A new tag
  • Application.cfc THIS members
  • Or …

What do you think?

37 responses to “How Would You Implement Per Application Settings?”

  1. Spike Avatar
    Spike

    With the vast array of potential settings that could be assigned per application, maybe a config path variable in the application scope would make sense. The config path would be an absolute path to a config file that holds all the custom settings.
    Maybe an AppConfig.cfc with rules the same as Application.cfc.

  2. Douglas Knudsen Avatar
    Douglas Knudsen

    so many ways. Wouldn’t using tags to set this stuff create security issues? You would have to be able to turn this ability off in the CFAdmin tool. If tied to eh application name in cfappliaction, shared hosts might not like this. Easy to guess these and muck up someone elses app, eh? Of course on an intranet like I work on, this is not such an issue. Maybe this could be incorporated in sandboxing somehow? ALONG WITH RDS SECURITY!!! 🙂

  3. Ryan Guill Avatar
    Ryan Guill

    my vote would be to add them as attributes to the cfapplication tag as well as application.cfc This. members. Although, cfsetting makes sense as well.

  4. Yacoubean Avatar
    Yacoubean

    I’d vote for Application.cfc

  5. Roland Collins Avatar
    Roland Collins

    Sounds like someone follows the CFCDev list 😉
    It would be great if the application scope it self were extended with a configuration scope/object. So in application.cfc, you could do something like:
    cfset this.name = "myApplication"
    cfset this.sessionManagement = true
    cfset this.sessionTimeout = CreateTimeSpan(0, 0, 20, 0)
    cfset this.mappings.add("cfc", "../cfc")
    cfset this.mailservers.add("mail.yourcompany.com")
    cfset this.debug = true
    That would be awesome.

  6. Doug Hughes Avatar
    Doug Hughes

    I might consider using an xml file or maybe a
    ".cfconf" file which contains xml. That way it’s easy to have different versions of the configuration for specific instances (dev, staging, live).
    Or maybe even in that xml define configurations for specific URLs, thus, I could turn debugging on in dev, but off in live without having to remember to distribute different versions of that file.

  7. Steve Collins Avatar
    Steve Collins

    I like Roland’s idea, in concert with Doug’s. So, a scope/object for application configuration, buildable as an external configuration file which gets included at application instantiation.

  8. Derek Perez Avatar
    Derek Perez

    Perhaps an XML file that is in the same directory as the presiding application.cfm/cfc. but with the same dynamics as the application.cfm/cfc, such as it looks for the closet instance of itself.
    or a reserved CFC like appconfig.cfc, i like that as well.

  9. Calvin Ward Avatar
    Calvin Ward

    I like the config file, the Application.cfc and cfapplication tag.
    cfsetting seems inappopriate as the current set of attributes appear to be request based.

  10. Sean Corfield Avatar
    Sean Corfield

    Application.cfc, this.xxx assignments.

  11. Jared Rypka-Hauer Avatar
    Jared Rypka-Hauer

    Application.cfc this scope attributes, preferrably in a situation where the can be provided by an XML config file and the CF Administrator can be configured with the settings that the XML file is allowed to override or add to.
    This would allow hosting services to provide users with a generated config file that includes only the settings that the user is allowed to override (and anything else would be ignored). Then instead of manually typing this scope attributes into Application.cfc, perhaps a special tag or two could be used.
    Also, then, <mappings /> could be part of that XML file.
    Laterz,
    J

  12. Hans Oberleitner Avatar
    Hans Oberleitner

    Well, maybe Macromedia should learn from Railo (www.railo.ch) 😉
    Railo supports global and local settings and a separate administration for every local instance.

  13. Bill Rawlinson Avatar
    Bill Rawlinson

    I’m not sure I like the idea of an XML file for a couple reasons; the most being that it goes against the simplicity that is CF in the first place.
    Everything we can do with CF is tag based. Having this one special exception to that rule where you need to write a valid XML document to use a certain feature set just seems clunky and like a hack.
    I think, in order to support this variety of settings a new tag should be introduced. CFAPPSETTING Setting="xxx" Value="yyy"
    How CF handles that, by populating the application.cfc this scope or something else, should be transparent to the user.
    If you provide an invalid setting name, or a value that is incompatiable for the setting name, then CF should throw an error like it does with every other syntax error.

  14. Jake Avatar
    Jake

    First off, let me say thanks for looking into this. As someone developing an application that is meant to be quickly and easily setup by people with every little CF skill, this is extremely important.
    I’m down with Doug Hughes’ suggestions and Roland’s ideas.

  15. Daniel D Avatar
    Daniel D

    I would suggest something like Java web.xml or .Net xml config file. IIS7 no incorperates the web.xml and .Net config file to allow both .Net and IIS config settings. Datasource, mappings, custom tag paths, smtp and mail setting would all be very usefull items to be able to config. Possibly the ability to set what config file to use as an attribute of the <cfapplication tag or this. scope in the application.cfc. By being able to define what config file to use and support for CF config settings being a subset of an exisiting XML document it might be possible for CF to read the same config file as IIS7 or use web.xml to hold its settings. I would definitely like to see the ability to select what config file is used for a application as I currently work on a project where there is one copy of the application but depending on what domain it is being access from changes what config it loads. Being able to do this nativly and to define datasources in this config would be extreamly usefull.

  16. Ryan Guill Avatar
    Ryan Guill

    The good thing about an xml file would be that we (or macromedia) could write a custom manager for the application to manage the xml, changing it on the fly through a browser interface instead of having to go into the code. Just a thought.

  17. Ben Rogers Avatar
    Ben Rogers

    Ryan, the reverse is also true. If we can programmatically add a mapping or a data source, then we could store that information in an XML file, ini file, a database, etc. We would only need to write a tool to read the configuration.
    Daniel, the beauty of the .Net approach is its flexibility. It can be used to set arbitrary properties on any object. You can, for instance, dynamically set the Web reference (WSDL URL) for a Web service. .Net handles all the mechanics (loading the config file, object instantiation, typing, etc.).
    That said, this is a very sophisticated abstraction that probably isn’t possible with ColdFusion. It’s heavilly dependent on the cohesive, object "orientedness" of the .Net Framework and ASP.Net application structure. ColdFusion simply wasn’t designed the same way.
    Consequently, I don’t think automatically read and parsed XML config files are the ideal solution for ColdFusion. I’d rather see a generalized mechanism for programmatically maintaining mappings, data sources, etc., one that allowed the developer to decide whether the mapping was persistent or nonpersistent, server or application level.
    On the administrative side, I’d like to be able to restrict whether or not an application can create mappings and data sources at the server level or just application level. Ideally, this would be part of sandbox security.
    I’d also like to be able to set mappings for individual sessions and requests. This would be of use when hosting multiple sites off the same code base where each "instance" of the application has its own set of assetts. Each session is tied to specific "instance" of the application, but they all run in the same ColdFusion named application.
    I think tags would provide the most consistent interface. We already have tags for scheduling, search. cfmapping and cfdatasource tags seem reasonable.
    -ben

  18. tony petruzzi Avatar
    tony petruzzi

    I’m in agreement with Ryan, the tag approach is best. The biggest problem I have with other programming langauages is the external configuration files. The beauty of CF is it’s syntax, tags make learning and reading the language easy. Try to read a .NET application without Visual Studio.
    That being said adding attributes to the CFAPPLICATION tag would be my vote.

  19. Jared Rypka-Hauer Avatar
    Jared Rypka-Hauer

    Tony –
    I don’t mind the idea of adding attrbutes to the cfapplication tag except for one thing… it’s already cumbersome. I mean, with attributes like sessionmanagement and applicationtimeout, the string itself gets to be long and ugly.
    The other problem with it is handling attributes that may need more than one argument, like mappings or dsns: mappings="/myMap,c:folderotherfolder" is nice unless you’ve got 3 mappings or something.
    I think cfdatasource and cfmapping would be awesome additions and allow us to write custom XML/database wrappers for our own application bootstrapping. Also we need to keep in mine that the underpinnings of this is J2EE and CFMX and JSP can share application and session scopes if they’re set up right.
    I’d still like to see the ability to treat the application scope like a CFC instance… so that we could do:
    application.addMapping("/mapName","c:mapPath")
    Although you could already do that by setting a UDF to an application-scope variable, I guess.
    I think that it would be cool to see anything set to application.this be accessible as application.varName, but applications can have a variables scope for protected data like mappings, datasources, etc. Adding get/set methods to the application instance would make it possible to set up custom instances of CF apps very simply and easily.
    Also maybe add a cfappconfig tag? Hehe… just a thought.
    Laterz,
    J

  20. matt wegrzyn Avatar
    matt wegrzyn

    Well, since we already have cf 7 and we introduced application.cfc, we can throw out the <cfapplication> tag, which should be deprecated in future versions. <cfsetting> wouldn’t be per application, having 1 cfsetting in 1 file and another in a second file in same application is confusing.
    Adding a new tag is confusing as well, sooner or later we’d need a dictionary for the tags and functions in cf, which is too much as it is.
    I prefer the THIS scope in an application.cfc. Lets not go back to cf mx 6.1 <cfapplication>. We already introduced this scope in cf mx 7, lets go from there, not backwards, but forward.

  21. Ben Forta Avatar
    Ben Forta

    A little OT, but, the if the size of the cfapplication tag (with lots of new attributes) becomes a concern then we could add a cfapplicationparam child tag, we already have that type of syntax as a precedent.
    — Ben

  22. Ryan Guill Avatar
    Ryan Guill

    As much as I like the new application.cfc and application events, I dont think its time to be deprecating application.cfm and the cfapplication tag for a while, definately not in the next version. One of the biggest points about coldfusion is its great backwards compatability, its never perfect, but its very close. deprecating the cfapplication tag would break a lot of existing apps very quickly.
    I also dont agree with the idea that we have too many tags and functions, or that new ones would make us to have too many. Progress in the language is going to need more tags and functions, theres just no way around that. If you dont remember what tag you need, thats what help text and livedocs are for.
    So basically, what Im trying to say is, if these abilities get put in the application.cfc This scope variables, it needs to be added some way to the cfapplication tag as well.

  23. Matt Wegrzyn Avatar
    Matt Wegrzyn

    Then it has to be added to both the cfapplication tag and the this scope. Otherwise, I won’t be able to use it in new versions that use Application.cfc, since .cfc doesn’t allow cfapplication tag.
    Either that or a new way to do it. But I’m getting a little tired of having alternate ways for every version of cf.

  24. Jeff Avatar
    Jeff

    I vote for adding them to Application.cfc . It is consistent w/ how CF operates right now.
    Potential confusion may arise when deciding which setting takes precedence. For example, the server wide setting for client variable storage can be overridden in the application. But, if the application session timeout value is larger than the server-wide value, then the server wide value will take precedence.
    I suppose that consistency issue could be addressed w/ documentation.

  25. John Farrar Avatar
    John Farrar

    The big feature would be add the feature!
    Second big issue is make sure it isn’t just added to enterprise.
    Third feature is to make sure it runs on shared hosting services without them getting hurt making sure everyone can use it.
    Now… about where. That is the forth issue, and hopefully the where will be kept in perspective to the three primary issues above. I would think it would be added to Application.cfc personally or cfapplication. The only issue I see with CF Application is that if you have things like "mappings" (note the plural case) you will need a scheme to allow multiple mappings. This is SOOOOO needed to add mappings that are controlled by the application rather than the external server. The reasons are plentiful… and powerful allies. The next question is actually which mapping takes control if there are two identical mappings. (Hopefully the one we are talking here would override the one set by the server mappings.)

  26. Ben Forta Avatar
    Ben Forta

    So, this is what I am thinking (based on all of the feedback thus far) …
    * Support additional cfapplication attributes and the same in THIS. In Application.cfc.
    * Some settings have single values, like smtpserver= or logfilepath= etc.
    * Same can have multiple values, like mappings. For this one it may be best to allow for a structure to be defined containing mappings, and then pass that structure as a value.
    * Setting a previously set mapping replaces it for this application.
    * A cfapplicationparam tag may make sense.
    * Any settings here override those set in CF Admin.
    * Sandbox security must be honored (so no setting a mapping where not allowed to go).
    * Values cannot be limited to fixed strings.
    Does that sound about right?
    If so, next question, what are the settings you’d want supported, in order of priority?
    — Ben
    PS I am not promising a feature at this point. I want to write up a spec for the CF team to discuss, and this is your chance to help define that spec.

  27. Ryan Guill Avatar
    Ryan Guill

    This is a great opportunity ben. I really want to thank you and macromedia for listening to its developers and what they are asking for.
    In order of priority, my vote goes to:
    mappings
    datasources (this is a big one too that hasn’t been mentioned. While im at it, it has been discussed elsewhere as well that the ability to define a default datasource in an application would save a lot of time as well. Many applications only have one datasource, and so the ability to say that for this application, the default datasource is x, then being able to leave out the datasource attribute in the cfquery could be nice)
    debugging
    mail settings, etc.
    Also, the ability to specify values that are not fixed strings is a big one too. I look forward to the time when we can supply dynamic values for extends="", cffunction returntype="" and cfargument type="".

  28. Jared Rypka-Hauer Avatar
    Jared Rypka-Hauer

    Ben,
    Sounds good…
    In order:
    * mappings, datasources, J2EE sesions on/off, and debug settings
    * mail settings
    * app, session, & client scope settings
    If there’s a way to do this within J2EE, it would be nice to add an attribute that allows an application scope to insist on a separate application scope so that it doesn’t show up when a cfapplication tag is used with no application name. This would drastically enhance the security of applications on shared servers.
    Thanks for the chance to shape the future of the platform.
    Laterz,
    J

  29. John Farrar Avatar
    John Farrar

    OK…
    1. Mappings (dynamic mappings prefered rather than hard coded)
    2. Override all admin settings (but sandbox security of course)
    3. Sandbox directory protection honored of course
    4. CFApplication makes sense, but not a priority for us. Since that is a legacy issue. Yet, the usage of this would be well advantaged there also so it is still a good priority.
    (While we are on the topic??? Should/could there be session mappings also?)
    (Also… it would be nice if the mappings allowed a CFImport type call also… so we can do the namespace style tag calls! That should be added to CFAdmin mappings also IMHO.)

  30. Nick Kwiatkowski Avatar
    Nick Kwiatkowski

    What I have seen done in another application, which I thought was pretty cool is to have the Administrator (CFIDE-Admin) be able to configure "admin pools" or "admin groups". In the CFIDE, you would have a drop down menu of what admin group you are currently working in. Within each CFAPPLICATION tag, you would then be able to set which admin-group’s preferences are to be used for that application.

  31. M!ke Dawson Avatar
    M!ke Dawson

    I’m all for using the THIS scope in application.cfc. Obviously, you do need to support application.cfm as well. I really don’t care what tag/sub-tag you choose as long as it is well-thought-out.
    Personally, I don’t care much for a configuration file. I’m not sure why, but it just doesn’t feel right to me.
    However, I’ll throw another idea out there…
    A few people are concerned about security issues with having configuration information clearly visible in the .cfm pages.
    What if, in the CF admininstrator, there was a new section called "Applications" and, in that section, you could define an application by name.
    The CF admin’s Applications section would let you assign different settings such as mail server, log file path, mappings, etc, and "attach" them to a name such as "IntranetApp".
    Then, in your application.cfc, you only need to specify this.name="IntranetApp". In application.cfm you use <cfapplication name="IntranetApp" …>. Then, CF resolves the application-specific settings from the administrator.
    This gives the server administrators the ability to "hide" the setting information from the developers.
    In essence, this is very similar to Datasources.
    As with a datasource and cfquery, you should be able to override "some" of the settings as needed.
    M!ke

  32. M!ke Dawson Avatar
    M!ke Dawson

    Nick, I should have read your comment a bit closer. I think you and I are talking about the same thing.

  33. Daniel D Avatar
    Daniel D

    Also for datasource creation should be able to store the password in an encrypted format in config file or code.

  34. Mark Drew Avatar
    Mark Drew

    I like the ideas presented above. I would like to add that I like the idea of setting:
    var this.<setting> = <value>/<struct>.
    As well as having this "hard coded" aproach, it would be nice if either in the <cfapplication> tag or programatically, you can point it to a cfg file. something like
    this.configfile = "<path to cfg file>"
    with the default being a directory under CFUSION. This would allow to have different version of servers that have settings that you dont need to deploy for dev/staging/live within the source controled code.
    It would make my life a whole lot easier rather than doing <cfswitch> statements based on the server.
    With regards to the ordering of importance of settings, I think it should go from the most changed values (name, sessionmanagement, etc) to the least changed (mailservers, security, RDS etc)
    Thanks for looking into this!

  35. Nando Avatar
    Nando

    I’m looking at the mapping aspect, and recognizing that setting a mapping to THIS. in Application.cfc, although on the surface of it may make a lot of sense, might make for some pretty clunky code in comparison to how other things work in CF. Each mapping would have 2 values, the name and the path, and there might often be multiple mappings defined for an application once this is rolled out.
    I initially liked the idea of mappings being application scoped because i currently need them that way, but as Vince over at Blue Dragon pointed out, in essence, an "Application" is defined very loosely in CF – wherever you drop your hat – or more precisely – wherever you drop your Application.cfm/c.
    So, since Applications are so loosely defined and can even overwrite each other in successive child directories or successive cfapplication tag calls, it seemed to make sense that mappings might just as well have the same flexiblity. Perhaps we shouldn’t think of mappings as needing necessarily to be application scoped, just because that is the need we see now. If we could define them at the drop of a cfmapping tag, that might make for the most flexible approach. Although i do agree that conceptually, most of us would view them as something you’d set application-wide.
    So if you’re using Application.cfm, you’d likely just drop one or a series of cfmapping tags in there that mirror the attributes now set in the cf admin panel and be done with it. Simple and clean
    If you’re using Application.cfc, then i’m a little foggy on what would be the best way to apply multiple mappings. But the simpliest thing that comes to mind in line with the above is just to put multiple cfmapping tags in onApplicationStart() or onRequestStart() – whichever winds up being appropriate. The passing in a structure idea seems a little too freestyle in the context of the rest of the language, but if that’s how it gets implemented, i’d be happy just to have it implemented in some form.
    Whether a cfmapping tag would result in a "significant" per request performance hit vs. mappings being set onApplicationStart, well, that’s something to consider. I was wondering if performance was the reasoning behind CFC paths being calculated at compile time rather than run time. But in the tradeoff between a very slight performance gain and the flexibility of a drop anywhere cfmapping tag, i’d be happy to go with a cfmapping tag.

  36. Joel Cox Avatar
    Joel Cox

    I think a cfapplicationparam tag makes sense, consistent with cfqueryparam, cfreportparam, cfhttpparam, etc.

  37. Luis Majano Avatar
    Luis Majano

    What about per application web service definitions???

Leave a Reply