Jon Flanders' Blog

How to store configuration data in the Enterprise Single Sign-On Database (SSO)

Friday, March 11, 2005 8:00:00 AM (GMT Standard Time, UTC+00:00)

One question that comes up often while teaching BizTalk is "Where do I put configuration data for my orchestration?". To answer this question we have to enumerate all the different configuration options and try to determine which one is preferable. Sometimes of course the answer depends.

The first option is to re-use the standard .NET configuration infrastructure. Each .NET exe gets a configuration file that starts with the name of the exe and ends with .config file extension. Because Orchestrations (and all BizTalk in-process code) run inside of the BizTalk host process (BTSNTSvc.exe) the configuration file to add items to is BTSNTSvc.exe.config.

The advantage to using the config file is that you can take advantage of built in elements like AppSettings, which allow you to have an arbitrary number of name/value pairs in the configuration file. Making changes to the file is easy because it is text based. You can also extend the elements the configuration infrastructure will recognize by creating and registering a custom configuration section handler.

There are of course a few disadvantages as well. First, because *all* orchestrations run inside of some instance of BTNTSvc.exe (depending on your Host configuration and Host bindings) all share the same configuration file. So it is easy to step on some element or changed needed for another orchestration. Another related issue is that the configuration file is on the hard-drive of a single BizTalk server machine. In a distributed environment with potentially multiple BizTalk Servers, this means you may have to copy configurations between multiple computers. Another disadvantage to the config file is that data cannot easily be encrypted (although there are various techniques to apply encryption after the fact, and of course .NET 2.0 is going to make encrypting the config file a very easy operation).

None of these problems are insurmountable. You could create a custom configuration section handler the allows you to delineate configuration data for multiple "applications" in one configuration file. You can also have that handler encrypt and decrypt your sensitive configuration data, and you can create manual or automatic processes for copying configuration between multiple servers in a BizTalk Group. Does any of that code sound trivial? Nope. How about fun? Maybe fun - but certainly not trivial or trivial to get 100% correct.

Other options include managing your configuration elsewhere - perhaps in a custom database, or inside of custom xml files (or other file types). Although these options are probably a little less error prone than a custom configuration section handler, there still is a lot of work to be done to make this work well, have the data be safe from prying eyes, and to make it work well in a distributed environment (well - perhaps the database option does this automatically).

Last Friday I ended up in a meeting in Redmond with a few members of the BizTalk dev team ( Suri Narayanan and Kevin Lam), BizTalk marketing Wizard Michael Woods, and Biztalk pattern Wizard Brandon Gross. We were talking about patterns and started talking about the best place to store configuration and we started talking about using the Enterprise Single Sign-on Service (SSO) as a configuration store. Of course in BizTalk, all Send Port and Receive Location Transport data is already stored in the SSO automatically. The reason for this is two fold. First, all that data needs to be easily distributed to multiple servers in a BizTalk group. Second, storing that particular configuration data in the SSO database (using the SSO API) means that it is stored securely (encrypted). This means if someone gets access to your configuration database they won't easily be able to see passwords, connection strings etc. This of course is just an extra measure of protection - but often a very useful one.

I think the simplest way to store configuration data is to use the BTSNTSvc.exe.config file and the System.Configuration namespace to access that data. In my mind the *best* way to store configuration data would be in the SSO, especially if you have a larger BizTalk deployment. You get automatic distributed configuration, plus automatic encryption (this is the advantage over the BTSNTSvc.exe.config even in small BizTalk deployments).

Of course the SSO API is published, but unfortunately all the samples are all about the typical usage of the SSO - storing alternate credentials for use by a Send Adapter when doing authentication. So I sat down to write an application that could be used to manage configuration with the SSO.

One of the first decisions I had to make in designing this system was what data format to use for storage. That was actually one of the easiest parts, because I've always been a big fan of Craig's XmlSerialization approach to configuration. So using XmlSerialization was pretty much a given. The other nice feature of this choice is that the configuration data can be retrieved as a strongly typed object, and accessing the data once the configuration has been loaded is much easier. Another part I felt was essential to making the SSO work as a configuration store was a nice UI (or a nice "developer" level UI ;-)). I'm a big fan of the WinForm's PropertyGrid control, so the way I wanted this app to work (I've also posted the code, so if you don't agree with the approach I took to the configuration system - feel free to take my code as starting point for your own system) was to have a system where you can specify a .NET type, have that .NET type get loaded into a PropertyGrid, and then be able to save the configuration inside of the SSO. And then at runtime, have a simple API for retrieving that data from the SSO (the SSO service does cache data, so there isn't any need to do any application level caching).

I also decided that the configuration data should be split up into "applications". One of the most frustrating things I find in working with BizTalk 2004 is the lack of this concept - essentially everything in a single Management Database (BizTalkMgmtDB) is considered part of the "application". I generally find when I work and the projects I've worked on, that a more partitioned approach is necessary (hence one of the motivating factors for BTSnapshot).

So the basic use case of this tool is to open the SSOAppConfig and to create a new "application" (New App from the File menu). To add an object you right-click on the ConfigData node in the tree view and select an assembly from the list of assemblies deployed in the GAC (since only those assemblies deployed in the GAC will able to be loaded by an orchestration). Once you pick the assembly, you get a list of Types (remember - the type has to be able to be serialized by the XmlSerializer *and* only public properties can be set via the Property Grid), you pick the Type you want to save in the configuration. The name of the object can be changed by right-clicking on the node in the tree view. It can save as many distinct objects as you'd like, the only requirement is the object has to have a unique name, and the object has to be able to be serialized by the XmlSerializer. As you add objects, the object's properties will appear in the Property Grid in the right hand pane of the UI.

The tool also allows for exporting and importing an application configuration file (commands for this on the File menu). The schema of this file is really simple. The root node is App with an attribute that holds the name of the application. The ConfigData node is next, and each child of ConfigData represents a single persisted .NET object. The variable name is used as the name of the top level element, and the inner element is the actual serialized XML.

Once you have save your application's configuration, you can access it easily inside of an orchestration. Add a variable for each "piece" of configuration you want to retrieve. The variable of course needs to be the same Type as the Type you picked when adding the configuration to the SSO. Add an expression with code similar to the following:

configData = (SSOConfigTestLibrary.TestData)SSOAppConfig.SSOConfigReader.GetConfig("AppOne","ConnectionData");
connString = configData.ConnectionString;//this could be any .net type that can be serialized using the XmlSerializer

So I'm posting the code now and later I'll post an exposition on how to use the SSO API in general. The solution (which can be found here has four projects in it. The SSOAppConfig is the Windows Forms application for managing the application configuration files. The SSOHelper is the assembly that does all of the actual work. Because many times it performs transactional updates it has to be registered as a COM+ application (only one of the classes inside of it derive from ServicedComponent). The SSOConfigTest library contains two test Types which can be serialized and stored in the configuration (again any .NET type that can be serialized using the XmlSerializer is fair game here). The SSOConfigOrchLib contain an orchestration and schema that shows an example of retrieving data from this API. I hope people find this useful - you can either choose to use the UI or write your own code again the SSOHelper assembly. If you have specific questions about the SSO API I'd love to hear them, as well as any suggestions on how to make this a better tool.

BizTalk   #    Comments [0]   

All comments require the approval of the site owner before being displayed.
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview