Posts
16
Comments
15
Trackbacks
0
Friday, May 23, 2008
TFS 2008 - Delete a Team Project and the "You are not authorized to access <machine>." message

After an oops with creating a team project in TFS 2008 with an incorrect name, I wanted to cleanup by removing the team project with the incorrect name.  However, someone else created the project and every time I tried to delete the team project using the tfsdeleteproject.exe command line tool, I got the error message:

"You are not authorized to access <machine>."

Uhhh, what?  I'm a domain admin in this domain.  How can this be?

After fumbling around a bit, I had a hunch and checked permissions on the TFS Team Project.  Sure enough, I had permissions on the TFS project, but I had no access to the Sharepoint site or the Reporting services reports.  After using the TFS Admin tool to grant myself permissions to these resources, I was able to delete the Team Project successfully.  The tool was failing to verify I had permissions to these; it would have been helpful to get this feedback rather than the generic "you are not allowed to access this server" message.

posted @ Friday, May 23, 2008 9:15 AM | Feedback (2)
Enterprise Library 3.1 - Different Configuration Sources Across Blocks

I recently had a co-worker inquire about using different configuration sources across different application blocks within the Enterprise Library.  As has already been demonstrated (both in the EntLib documentation and on various websites), it's extremely simple to modify the source of configuration information for the entire Enterprise Library.  This is provided both by the EntLib framework and the configuration tool.  Simple create a new/alternate Configuration Source, set it as the default configuration source, and away you go.  You can use one of the out-of-the-box configuration sources (alternate file source, e.g.) or write your own (put configuration in Sql, a flat file, registry, or whatever you can conjure up).

However, splitting configuration between different application blocks is slightly different.  It's not truly natively supported by EntLib, but the pieces needed to achieve this are present in the framework, and the customization required to pull it off is extremely straightforward.

To demonstrate, I'll pull configuration for a single application block from a separate configuration file.  In theory, and as I described earlier, this can be from any source for which a ConfigurationSource provider exists.

First, create your EntLib configuration.  In my case, I've got the Data Application Block and Caching Application Block defined/configured.  I've also created an alternate config source entity called 'Cache Configuration Source'.  It points to another file called separateconfig.config.

entlib.configuration entlib.configuration.properties

Now, the default configuration source is still the System Configuration Source, which is the application's configuration file (application.exe.config).  However, I've also created a separate configuration file called separateconfig.config that I want to pull Cache Application Block configuration data from.  What I'll do is copy the configuration (including the configSection declaration) from app.config to separateconfig.config for the caching application block:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:   <configSections>
   4:     <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   5:   </configSections>
   6:   <cachingConfiguration defaultCacheManager="Cache Manager">
   7:     <cacheManagers>
   8:       <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"
   9:           numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
  10:           name="Cache Manager" />
  11:     </cacheManagers>
  12:     <backingStores>
  13:       <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
  14:           name="Null Storage" />
  15:     </backingStores>
  16:   </cachingConfiguration>
  17: </configuration>

You can remove this corresponding configuration from the original app.config, although this has implications on configuring this data in the future (more on this later).  Now we have to figure out how to pull this configuration when instantiating the CacheManager from the EntLib.  The default CacheFactory simply uses the default configuration source (our app.config file) to pull configuration.

   1: // native EntLib functionality
   2: return CacheFactory.GetCacheManager();

Under the hood, however, what's going on is that the CacheManagerFactory is being passed the default ConfigurationSource and instantiating the CacheManager from that configuration.  If we can override the ConfigurationSource being used, then we're golden.  Luckily, the lower-level CacheManagerFactory class allows us to do just that.  So, we simply create our own implementation of the CacheFactory class and return a singleton, as follows:

   1: // only needed if we are overriding the default CacheFactory singleton
   2: private static CacheManager cacheManager = null;
   3: private static object lockObject = new object();
   4: // only needed....
   5:  
   6: private static CacheManager GetCacheManager()
   7: {
   8:  
   9:     // Custom behavior -- use a different config source
  10:     // In order to provide this, we don't use the default CacheFactory behavior; we create our own.
  11:  
  12:     if (cacheManager == null)
  13:     {
  14:         lock (lockObject)
  15:         {
  16:             if (cacheManager == null)
  17:             {
  18:                 // Create a custom configuration source
  19:                 IConfigurationSource cacheSource = ConfigurationSourceFactory.Create("Cache Configuration Source");
  20:                 CacheManagerFactory managerFactory = new CacheManagerFactory(cacheSource);
  21:  
  22:                 cacheManager = managerFactory.CreateDefault();
  23:             }
  24:         }
  25:     }
  26:  
  27:     return cacheManager;
  28:  
  29: }
  30:  

As you can see in the code snippet, the Configuration being used to construct a CacheManager is from the "Cache Configuration Source" configuration source that we defined in the system configuration (the app.config).  In short, we're pulling from separateconfig.config to construct the CacheManager class.

Pulling this configuration from a separate location has an implication on design-time configuration.  Natively, the configuration tool can't persist configuration to different locations at the same time (it simply writes to the default configuration source).  I suppose you could investigate modifying the configuration tool to support this functionality, but I haven't explored this myself.  I have also seen community-developed tools that will allow you to specify a configuration section and use an alternate ConfigurationSource provider to persist the configuration to an alternate location, but this would always by a manual post-configuration deployment task.  In the end, how you achieved this would depend on the effort required to customize the tools or your workflow and the cost associated with the manual effort of persisting the configuration where it ultimately needed to go.

posted @ Friday, May 23, 2008 8:52 AM | Feedback (0)
News