ASP.NET Custom Configuration Sections and Group Policy Aware Configuration Providers

Part 3 - Using the Enterprise Library Manageable Configuration Extensions with ASP.NET

 

©2007 Alex Homer, Stonebroom Limited, http://www.stonebroom.com

This series of three articles shows how you can create custom configuration sections in your ASP.NET application configuration file, and expose the data they contain within your application using custom providers. The articles also describe how you can use Windows Group Policy at both the machine and domain level to control configuration settings from a central location, and impose these settings on some or all of the servers that run your Web applications. Finally, the third article shows an example of how these techniques are used to great effect in existing products; by demonstrating how you can use the Manageable Configuration Provider that is part of Microsoft's Enterprise Library.

Contents

Introduction. 1

Manageable Configuration in Enterprise Library. 2

The Manageable Configuration Example Application. 2

Adding the Manageable Configuration Source. 5

Configuring the Manageable Configuration Source. 7

Creating the Group Policy Administrative Template. 7

Setting Configuration Values in Group Policy. 9

Testing the Manageable Configuration Source. 11

So, Why is All This Useful? 13

Summary. 14

Introduction

ASP.NET applications usually rely on two of the standard sections in a Web.config file: the <appSettings> section for holding general configuration and application values, and the <connectionStrings> section that is specialized to store connection details for data providers such as database servers.

However, custom configuration sections are useful where an application requires complex sets of configuration data that the .NET configuration system can expose, and automatically validate. It is easy to create custom configuration sets and the related classes that expose this data.

When it comes to actually managing configuration values, the common approach is to simply update and deploy the Web.config file to all servers running the application. However, the ASP.NET configuration system provides no central mechanism for controlling the values in a Web.config file, which means that – if you have multiple servers such as a Web farm – the Web.config files can become unsynchronized. For example, local operators can change values in Web.config on specific machines.

Group Policy provides a mechanism for centrally managing features of the operating system and the applications that run upon it. You can take advantage of Group Policy to create a mandatory and centrally managed environment for configuration settings for your Web applications by creating a custom Group Policy Object (GPO) and building Group Policy awareness into your configuration code.

In these articles, you will see an example of a custom configuration section and the use of a Group Policy aware configuration system. Of course, you can create Group Policy aware code that reads configuration information from the <appSettings> and <connectionStrings> sections of Web.config using the technique shown in these articles. Alternatively, as demonstrated, you can combine the custom configuration provider and Group Policy aware techniques so that the configuration classes that expose the custom configuration information are themselves Group Policy aware.

Manageable Configuration in Enterprise Library

Enterprise Library 3.0, from Microsoft's patterns & practices group, includes a Manageable Configuration Source provider that implements a process very similar to that you saw in previous articles in this series (for details, see http://www.daveandal.net/articles/GPAwareConfig/).

The provider loads the application configuration data from a local Web.config or App.config file. For each value exposed in the configuration, it looks in Windows Registry for the corresponding key to see if Group Policy settings define a value for this setting. If there is a Group Policy value, the provider returns this instead of the value in the configuration file.

The documentation for Enterprise Library contains step-by-step guides to setting up and using the Manageable Configuration Source provider. In this article, you will see this process briefly explained within the context of an example application, and discover how the final configuration affects the behaviour of the application.

The Manageable Configuration Example Application

The example application makes use of four of the Enterprise Library Application Blocks:

 

 

Figure 1 shows the example application. It is, in fact, based on the example used in a previous series of articles "Using Enterprise Library in ASP.NET". You can read these to see how the example works, and how it uses the Enterprise Library application blocks and a custom caching provider, at http://www.daveandal.net/articles/EntLibASPNET/.

Figure 1 – The example application that demonstrates how you can use the Manageable Configuration Provider in Enterprise Library

The example uses the two databases defined within the Data Access Application Block configuration to fill two list boxes with the names of products from Microsoft's "Northwind" sample database. By default, they use the SqlClient and the OleDbClient providers, as indicated by the connection strings displayed in the text boxes below each list.

The page also contains a button that allows you to create a DataSet using the default database defined for the Data Access Application Block, and cache it using the default caching provider defined for the Caching Application Block (the Isolated Storage Cache provider). Next to this is another button that retrieves the DataSet from the default cache and displays the rows in the GridView control on the page.

Finally, there are three buttons that use features of the Cryptography Application Block to create a hash of the text in the TextBox control above the buttons, encrypt this text, and decrypt it again.

Adding the Manageable Configuration Source

The first step in using the Manageable Configuration Source provider is to create the application you want to manage. Each time you add or remove application blocks, providers, and other Enterprise Library features within the application configuration, you change the requirements of the administrative template that the Manageable Configuration Source uses. Therefore, you should build, test, and debug your application before adding the manageability features.

Once the application is complete:

  1. Open the Web.config file into one of the two configuration editors (the Configuration Console or the Visual Studio Configuration Editor).
  2. Right-click on the entry for the application (the node immediately below the "Enterprise Library Configuration" node), select New..., and click Configuration Sources. This adds a Configuration Sources node and a child System Configuration Source node to the configuration tree.
  3. Right-click on the new Configuration Sources node, select New..., and click Manageable Configuration Source.
  4. Right-click on the System Configuration Source child node that was added by default and click Remove to remove it from the configuration.

Figure 2 shows the final configuration of the example application. You can see in this screenshot the Configuration Sources section containing the Manageable Configuration Source. The next step is to set the properties of the Manageable Configuration Source provider.

Figure 2 – The configuration for the Enterprise Library Manageable Configuration example opened in the Visual Studio Configuration Editor

Configuring the Manageable Configuration Source

The Manageable Configuration Source has six properties, five of which you can set using the configuration tools. At a minimum, you must set the ApplicationName and File properties. The ApplicationName property defines the name of the root Registry key (within the HKEY_LOCAL_MACHINE\Software\Policies\ section) that the provider will read to find Group Policy configuration values. The default is "Application".

The File property defines the full path to the configuration file (Web.config in this example) from which the provider will read local configuration values. You can also specify the name for the provider.

Two other properties, EnableGroupPolicies and EnableWmi, specify if the provider will read Group Policy values and/or emit details of the configuration through WMI. By default, both are set to True, though you can disable them as required. For example, you can turn off WMI property and event generation if you do not require this feature, or disable Group Policy while you test and experiment with your application configuration.

You must also set the SelectedSource property of the parent Configuration Sources node to specify the Manageable Configuration Source you are using. You can select this from the drop-down list in the SelectedSource property of the Configuration Sources node.

If you want to encrypt this section of the configuration file, select a value in the drop-down list for the ProtectionProvider property of the Configuration Sources node. Finally, if you intend to run your application in partial trust mode, set the RequirePermission property of this node to False.

Now save your configuration file and test your application to ensure that it reads the configuration information correctly, and that there are no errors. You may find that you need to add references to other application block assemblies (or copy the assemblies to your Bin folder) for blocks and features that the manageable provider uses. Visual Studio generates an exception that indicates any missing assemblies when you run the application.

Creating the Group Policy Administrative Template

With the application complete, and the Manageable Configuration Source added to the configuration, you can create the Administrative Template that defines the Group Policy Object required to administer the application through Group Policy. The configuration tools can automatically generate a suitable template, which you can edit afterwards if required.

To create the template, right-click on the Manageable Configuration Source node in the configuration editor tree, and click Generate ADM Template. Specify the file name and location in the Save As dialog. The configuration editor generates the file automatically. Afterwards, you can open it in a text editor (or Visual Studio) to view the contents.

Notice that the file contains a CLASS MACHINE section and a CLASS USER section containing the same content. For an ASP.NET Web application (as discussed in the previous article in this series), you will probably not require the CLASS USER section, and so you can remove it from the ADM file.

The configuration tool generates a full set of PARTS (controls) for each configuration setting, including drop-down lists where appropriate. However, it does not generate any EXPLAIN text other than the very brief note of the section that the settings apply to. You may wish to expand this, perhaps using a [strings] section within the file as demonstrated in the previous article. The template files (named EntLibManageable.adm) included with the example application have not been edited, so that you can see the default content that the configuration tools generate.

To give you a feel for the kind of content in the administrative template, the following listing shows the category that defines the settings for the Caching Application Block. Notice that it uses nested categories to give a structure of multiple levels within the root key named "EntLibManageableSample":

CLASS MACHINE

CATEGORY "EntLibManageableSample"

CATEGORY "Caching"

CATEGORY "Cache managers"

  POLICY "Specify settings for cache manager 'Cache Manager'"

    KEYNAME "Software\Policies\EntLibManageableSample

             \cachingConfiguration\cacheManagers\Cache Manager"

    VALUENAME "Available" VALUEON NUMERIC 1 VALUEOFF NUMERIC 0

    PART "Expiration poll frequency (secs.)"

      NUMERIC

      VALUENAME "expirationPollFrequencyInSeconds"

      DEFAULT 60

      MIN 0

    END PART

    PART "Maximum elements in cache before scavenging"

      NUMERIC

      VALUENAME "maximumElementsInCacheBeforeScavenging"

      DEFAULT 1000

      MIN 0

    END PART

    PART "Number to remove when scavenging"

      NUMERIC

      VALUENAME "numberToRemoveWhenScavenging"

      DEFAULT 10

      MIN 0

    END PART

    PART "Backing store settings"

      TEXT

    END PART

    PART "Partition name"

      EDITTEXT

      VALUENAME "partitionName"

      KEYNAME "Software\Policies\EntLibManageableSample

               \cachingConfiguration\backingStores\Isolated Storage"

      MAXLEN 255

      REQUIRED

      DEFAULT "ASPNET-EntLib"

    END PART

  END POLICY

  ... more settings for caching application block here ...

END CATEGORY  ; "Cache managers"

END CATEGORY  ; "Caching"

END CATEGORY  ; "EntLibManageableSample"

 

The policies defined in the section of the template shown above provide the controls to set the configuration of the Caching Application Block for any application that has "EntLibManageableSample" as the ApplicationName property of its Manageable Configuration Source provider. You can see that this provides a useful opportunity for managing multiple applications from one policy. However, bear in mind that you can only configure one Manageable Configuration Source provider for an application. 

Figure 4 shows the Group Policy Object Editor displaying the settings for the section of the administrative template shown earlier, together with the sections for the other application blocks defined within the example application. 

Figure 3 – The machine-level settings generated by the example application administrative template in the Group Policy Object Editor; notice how the nested categories in the template create a nested hierarchy of settings

Setting Configuration Values in Group Policy

After installing the administrative template, the next step is to set the values you require for the application settings. You do not, of course, have to set all of the values. Only settings enabled in Group Policy will replicate to Windows Registry, and therefore affect the application.

Figure 4 shows an example of setting values for the sample application. You can see that the settings for "Cache Manager" (the Isolated Storage cache manager and backing store added to the application configuration) are enabled. The controls in the dialog allow you to specify settings such as the expiration poll frequency, number of items to remove when scavenging, and the Isolated Storage partition name for storing cached values.

Figure 4 also shows the single setting available for the Data Access Application Block (the settings for each database connection are in child nodes below this node). The drop-down list shows all the available connections defined within the configuration, and you can choose the one that will be the default if code does not specify which database connection to use.

Figure 4 – Setting the values for the Data Access and Caching Application Blocks in the Group Policy Object Editor

 

The setting you specify do not replicate immediately. You can log off the target machine and log on again to force the application of local policies, or restart the target machine to force the application of domain-level policies. Otherwise, they will be applied during the next security policy update cycle.

After replication of the Group Policy settings, you can view the results in Windows Registry Editor (regedit.exe). Figure 5 shows the section from the HKEY_LOCAL_MACHINE hive that contains the example application settings specified in Group Policy. You can see that only those enabled within Group Policy appear in the Registry, and they are arranged in the same hierarchy as in the Group Policy Object Editor.

Figure 5 – The machine-level settings for the example application in Windows Registry; only a few of the settings have been enabled and configured in Group Policy 

Testing the Manageable Configuration Source

The example application uses the Enterprise Library Manageable Configuration Source provider to make it Group Policy aware. When you run the application with no Group Policy settings enabled, or if you set the EnableGroupPolicies property of the Manageable Configuration Source to False, it displays the default behaviour. The left-hand list box uses the default SqlClient database provider, whereas the right-hand one uses the OleDb provider (see Figure 6).

Figure 6 – The default behaviour of the two lists populated from the Northwind database when Group Policy is not applied 

This is because the code that populates the left-hand list does not specify a database provider type, and so the Data Access Application Block generates one using the type specified as the default in the Web.config file:

Database db = DatabaseFactory.CreateDatabase();

 

However, the code that populates the right-hand list does specify a database provider type – the LocalOleDbConnection defined in the Web.config file:

Database db = DatabaseFactory.CreateDatabase("LocalOleDbConnection");

 

In addition, the code that runs when you click the Cache a Dataset to Disk button uses the default cache manager, as specified in the Web.config file:

CacheManager diskCache = CacheFactory.GetCacheManager();

 

To see the effects of Group Policy, specify the settings in the Group Policy Editor for the Default database (in the Specify Database Block settings section) and the Default Cache Manager (in the Specify settings for Caching Block section). For example, select LocalOleDbConnection as the default database, and Custom Cache Manager as the default cache manager.

 

Now, when you run the example (after the settings replicate to Windows Registry), you see that the code that populates the left-hand list box is now using the OleDb database provider instead of the SqlClient provider. The Manageable Configuration Source reads this setting from the Registry and exposes it as the DefaultDatabase property for the Data Access Application Block (see Figure 7).

Figure 7 – The setting for the default database in Group Policy changes the behaviour of the application to use the OldDb provider for both lists, instead of using the SqlClient provider for the left-hand list 

In addition, if you now click the Cache a DataSet to Disk button, you will see two files appear in your C:\Temp folder (provided that you have this folder on your disk, and that ASP.NET has permission to write to it!). The Group Policy settings change the default cache manager from "Cache Manager", which uses the Isolated Storage backing store provider, to "Custom Cache Manager", which uses the custom file-based backing store provider (see Figure 8).  

Figure 8 – The setting for the default cache manager in Group Policy changes the behaviour of the application to use the custom caching backing store provider, which writes cached data to disk files instead of Isolated Storage 

Other Group Policy settings you can experiment with in the example application include:

So, Why is All This Useful?

One of the strengths of Enterprise Library, besides the more obvious features such as providing you with ready-built and tested code that simplifies development, is that you can change the behaviour of the application blocks and the core functionality through configuration. This reduces downtime and removes the error-prone task of updating the code and recompiling.

However, unless you store configuration centrally (for example, in a shared database), each instance of the application requires a local configuration file that defines the behaviour of that instance. In a server farm for an ASP.NET application, or in an office where there are hundreds of desktop machines, application configuration files may become out of synch as administrators (and users, if they have permission) edit the file to solve problems, debug code, or just to experiment with settings.

Group Policy allows you to apply and enforce settings for an application, and ensure that all machines within an Active Directory forest or domain contain the correct settings. It is still possible for users that have access to the local configuration file to change the behaviour (they could simply remove the Manageable Configuration Source provider from the configuration!), but changing settings will otherwise have no effect.

In addition, Group Policy makes updates to configuration easier, removing the requirement for administrators to visit each machine, or remotely deploy updated versions of the configuration files. And, when situations or requirements change, administrators can quickly apply new configuration settings to all machines. For example, if failure of a database server should occur, it is easy to change Group Policy settings to point all the machines at a different database server. 

Summary

Developers are increasingly pressured into building applications that are more manageable. It is an accepted fact that deployment, runtime, and maintenance costs make up over 80% of the lifetime cost of an application, and any techniques that can help to minimize these costs are extremely welcome.

Managing application configuration is a major part of the deployment and runtime tasks that administrators face, and best practice in application design and development tends towards central management of configuration data, together with the ability to impose specific configurations on users and groups of machines. In the ASP.NET arena, being able to control centrally configuration for multiple servers, such as a Web farm, reduces the cost and complexity of updating and managing Web.config files.

This series of articles describes how you can create custom configuration sections and providers that automatically verify the presence of configuration data matching a required schema, and expose this data through objects and properties that make it easy to consume the data within applications.

Secondly, the articles describe how you can use Windows Group Policy to centrally manage configuration information, and impose specific values on all machines and users. By using these techniques within a custom configuration provider, you can easily build Group Policy aware configuration systems that automatically provide the advantages of centralized administration and control.

Finally, to demonstrate how these techniques are used in the "real world", the articles describe how version 3.0 of Microsoft's Enterprise Library provides the same kinds of capabilities through its own Manageable Configuration Provider mechanism.

 

©2007 Alex Homer, Stonebroom Limited, http://www.stonebroom.com