Potential BlobConfigurationSource issues with Dev emulators

Topics: Windows Azure Integration Pack
Dec 19, 2011 at 12:35 PM

Hi Everybody,

I am starting a new Windows Azure project and I thought it prudent that I use the Enterprise Library Integration Pack for Azure. After my investigation I decided the following:

- I am implementing an Autoscaler Worker Role
- I am using Transient Fault Handling
- I am storing all of my configurations in blobs to be accessed using the BlobConfigurationSource

I started with the Autoscaler Worker Role, and once I had the basics in place, I implemented the BlobConfigurationSource... This is where all of my troubles started.

First I need to get the configuration files into blob storage. I created a new config file (Diagnostic.Worker.config) and used the Enterprise Library Configuration tool to set it up. I added this file as Content to my project and set it to Copy Always. See the code below:

CloudStorageAccount storageAccount = ConfigurationProvider.GetStorageAccount(ConfigurationProvider.DefaultStorageConfigurationString);

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

CloudBlobContainer container = blobClient.GetContainerReference(BlueMarble.Shared.AzureConstants.BlobContainers.EnterpriseLibraryContainer);

container.CreateIfNotExist();

BlueMarble.Azure.Blob.BlobProvider b = new BlobProvider(storageAccount.Credentials, storageAccount.BlobEndpoint, BlueMarble.Shared.AzureConstants.BlobContainers.EnterpriseLibraryContainer);
b.UploadStream("Diagnostic.Worker.config", new System.IO.MemoryStream(System.IO.File.ReadAllText("Resources\\Diagnostic.Worker.config").ToUtf8ByteArray()), true);

Next I put the Autoscaler rule and service information files into blob storage as well:

CloudBlobContainer autoscalerContainer = blobClient.GetContainerReference(BlueMarble.Shared.AzureConstants.BlobContainers.AutoScalingContainer);
            
autoscalerContainer.CreateIfNotExist();

b = new BlobProvider(storageAccount.Credentials, storageAccount.BlobEndpoint, BlueMarble.Shared.AzureConstants.BlobContainers.AutoScalingContainer);
b.UploadStream("default-rules-set.xml", new System.IO.MemoryStream(System.IO.File.ReadAllText("Resources\\default-rules-set.xml").ToUtf8ByteArray()), true);
b.UploadStream("default-service-information-set.xml", new System.IO.MemoryStream(System.IO.File.ReadAllText("Resources\\default-service-information-set.xml").ToUtf8ByteArray()), true);

Note: I upload the files and overwrite them each time because this is debug code, obviously when I deploy to production I will only copy the file if it does not exist yet.

The next step is to load the BlobConfigurationSource:

blobConfigurationSource = EnterpriseLibraryContainer.Current.GetInstance<BlobConfigurationSource>();

This is the step where my problems occur. Here is the error that I get:

A first chance exception of type 'Microsoft.Practices.Unity.ResolutionFailedException' occurred in Microsoft.Practices.Unity.dll
A first chance exception of type 'Microsoft.Practices.ServiceLocation.ActivationException' occurred in Microsoft.Practices.ServiceLocation.dll
Microsoft.WindowsAzure.ServiceRuntime Critical: 1 : Unhandled Exception:
Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type BlobConfigurationSource, key "" ---> Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Configuration.BlobConfigurationSource", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.AzureStorage.ICloudStorageAccount, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:

  Resolving Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Configuration.BlobConfigurationSource,(none)
  Resolving parameter "storageAccount" of constructor Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Configuration.BlobConfigurationSource(Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.AzureStorage.ICloudStorageAccount storageAccount, System.String blobContainerName, System.String blobName, System.TimeSpan refreshInterval)
    Resolving Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.AzureStorage.ICloudStorageAccount,(none)
 ---> System.InvalidOperationException: The current type, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.AzureStorage.ICloudStorageAccount, is an interface and cannot be constructed. Are you missing a type mapping?
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface(IBuilderContext context)
   at BuildUp_Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.AzureStorage.ICloudStorageAccount(IBuilderContext )
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey)
   at Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
   at BuildUp_Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Configuration.BlobConfigurationSource(IBuilderContext )
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
   --- End of inner exception stack trace ---
   at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
   at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable`1 resolverOverrides)
   at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides)
   at Microsoft.Practices.Unity.UnityServiceLocator.DoGetInstance(Type serviceType, String key)
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 49
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 57
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService]() in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 90
   at BlueMarble.Diagnostic.Worker.WorkerRole.OnStart() in C:\Development\Rockefeller\Management\Diagnostic.Worker\WorkerRole.cs:line 64
   at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum)
   at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRole(RoleType roleType)
   at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.b__0()
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Here is my App.Config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <enterpriseLibrary.ConfigurationSource selectedSource="Blob Configuration Source">
    <sources>
      <add name="Blob Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Configuration.BlobConfigurationSource, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Configuration, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          blobContainerName="enterpriselibrary-container" blobName="Diagnostic.Worker.config"
          storageAccount="UseDevelopmentStorage=true" refreshInterval="00:00:30" />
    </sources>
  </enterpriseLibrary.ConfigurationSource>
</configuration>

And my Diagnostic.Worker.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="autoscalingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.Configuration.AutoscalingSettings, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    <section name="typeRegistrationProvidersConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.TypeRegistrationProvidersConfigurationSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <autoscalingConfiguration dataPointsStoreAccount="UseDevelopmentStorage=true"
    ruleEvaluationRate="00:00:30" loggerName="Logging Block Logger"
    rulesStoreName="Blob Rules Store" serviceInformationStoreName="Blob Service Information Store">
    <loggers>
      <add name="Logging Block Logger" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.Logging.LoggingBlockLogger, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </loggers>
    <rulesStores>
      <add name="Blob Rules Store" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.Rules.Configuration.BlobXmlFileRulesStore, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        blobContainerName="autoscaling-container" blobName="rules-store.xml"
        storageAccount="UseDevelopmentStorage=true" monitoringRate="00:00:30" />
    </rulesStores>
    <serviceInformationStores>
      <add name="Blob Service Information Store" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.ServiceModel.Configuration.BlobXmlFileServiceInformationStore, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        blobContainerName="autoscaling-container" blobName="service-information-store.xml"
        storageAccount="UseDevelopmentStorage=true" monitoringRate="00:00:30" />
    </serviceInformationStores>
    <advancedOptions>
      <serviceManagementRequestTracker trackServiceManagementRequests="true"
        storageAccount="UseDevelopmentStorage=true" trackingRate="00:01:00" />
      <executionLease useBlobExecutionLease="true" blobExecutionLeaseStorageAccount="UseDevelopmentStorage=true"
        blobExecutionLeaseBlobContainerName="autoscaling-container" />
    </advancedOptions>
  </autoscalingConfiguration>
  <typeRegistrationProvidersConfiguration>
    <clear />
    <add name="Caching" sectionName="cachingConfiguration" />
    <add name="Cryptography" sectionName="securityCryptographyConfiguration" />
    <add name="Exception Handling" sectionName="exceptionHandling" />
    <add name="Instrumentation" sectionName="instrumentationConfiguration" />
    <add name="Policy Injection" sectionName="policyInjection" />
    <add name="Security" sectionName="securityConfiguration" />
    <add name="Data Access" providerType="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSyntheticConfigSettings, Microsoft.Practices.EnterpriseLibrary.Data" />
    <add name="Validation" providerType="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationTypeRegistrationProvider, Microsoft.Practices.EnterpriseLibrary.Validation" />
    <add sectionName="autoscalingConfiguration" name="autoscalingConfiguration" />
  </typeRegistrationProvidersConfiguration>
</configuration>

Note: If I replace my App.Config with the Diagnostic.Worker.config and remove the call to the container for the BlobConfigurationSource, instead calling the container directly for the Autoscaler, everything loads up just fine.

I am unsure what is causing this behavior and I really want to have the BlobConfigurationSource working properly. I realise that the Enterprise Library Windows Azure Integration Pack was only recently released. There is no help available on the internet for this, and the TailSpin RI has no implementation of the BlobConfigurationSource, and neither do any of the ENTLIB WAG Labs (Part 1, 2 and 3).

Can somebody please tell me what I am doing wrong

 

Regards

Stephan

Dec 19, 2011 at 5:51 PM

Hi Stephan,

You should not be getting the BlobConfigurationSource from the container, as it will not be registered (in fact calling the container will bootstrap and load up the referenced config sources). The configuration source will be used automatically, as you have rightfully specified the Blob Configuration source as your selectedSource:

      <enterpriseLibrary.ConfigurationSource selectedSource="Blob Configuration Source">

 

So your consuming code should not change if you are using a different config source or the main app.config, and you should be getting the Autoscaler object from the container directly. Can you try this and see if it works?

Thank you,
Julian

Dec 19, 2011 at 6:39 PM

Hi Julian,

Thank you that did change things up a bit on my side :) And it makes sense, I use Unity with Prism in another project, I should have figured that the container would load everything up it knew about as soon as I call it...

Anyway, now I have a new, and much more perplexing error. I have changed the line where I call the EnterpriseLibraryContainer to get an instance of BlobConfigurationSource to the following:

blobConfigurationSource = new BlobConfigurationSource(
  AzureStorageAccount.DevelopmentStorageAccount,
  BlueMarble.Shared.AzureConstants.BlobContainers.EnterpriseLibraryContainer,
  "/Rockefeller.Services/Diagnostic.Worker/config",
  new TimeSpan(0, 15, 0));

The error highlights the AzureStorageAccount.DevelopmentStorageAccount and says:

error CS0433: The type 'Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.AzureStorage.AzureStorageAccount' exists in both 'c:\Development\Rockefeller\Solutions\Rockefeller\packages\EnterpriseLibrary.WindowsAzure.Autoscaling.5.0.1118.0\lib\NET4\Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.dll' and 'c:\Development\Rockefeller\Solutions\Rockefeller\packages\EnterpriseLibrary.WindowsAzure.Configuration.5.0.1118.0\lib\NET4\Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Configuration.dll'

??

I think its the right time to mention how I installed Enterprise Library on my Visual Studio as I believe this might have something to do with this issue:

1) I opened NuGet and searched for entlib

2) I selected EnterpriseLibrary Exception Handling Logging Block package (as this will install CommonServiceLocator/Common Infrastructure/Exception Handling & Logging packages for EntLib)

3) I searched for elazure

4) I installed the Transient Fault Handling package

5) I installed the Autoscaling package

6) I installed the Blob Configuration Source package

I chose not to install the Integration Pack (I believe it contains all three options) since I have been using the individual packs on my other projects and only selected each package where I will be using it.

So this kinda explains how I got this error, but when I go to resolve the error by uninstalling the Transient Fault Handling, Autoscaling and Blob Configuration Source packages, and reinstall just the Integration Pack... I get a simple error:

------- Installing...EnterpriseLibrary.Source.WindowsAzure 5.0.1118.0 -------
'EnterpriseLibrary.Source.WindowsAzure 5.0.1118.0' already installed.
==============================

I have tried this many times including restarting Visual Studio and the Azure dev tools. I've even rebooted my pc and Visual Studio Refuses to install this pack.

 

Any ideas?

Dec 19, 2011 at 7:24 PM

Hi,
I guess I was not very clear. What I meant is that you should not have to resolve the configuration source from the container, nor instantiate it by hand. Just resolve what you actually need from the container. In this case do:

var autoscaler = EnterpriseLibraryContainer.Current.GetInstance<Autoscaler>();

Or do you actually want a reference to the blob configuration source for some other reason? If you do not, when getting the Autoscaler, the bootstrap logic will implicitly get the blob configuration source and download the blob content automatically. That's what I meant about not changing the consuming code.

If for some reason you do want to access a configuration source explicitly, you can use the ConfigurationSourceFactory class to do that.

Hope this helps,
Julian

Dec 19, 2011 at 7:31 PM
juliandominguez wrote:
I guess I was not very clear.

Don't be so hard on yourself :) I believe that I underestimated how easy you guys have made this.

I have just removed all code to try and get the BlobConfigurationSource and my Autoscaler starts up perfectly reading the configuration from the Azure Blob.

 

Thank you so much Julian

Dec 22, 2011 at 8:35 PM

hi Julain,

I ma facing the Issue when using the creating the instaced of autoscaller

            Autoscaler scaler = null;
                scaler = EnterpriseLibraryContainer.Current.GetInstance<Autoscaler>();
                scaler.Start();

I get any expection message as

Activation error occured while trying to get instance of type Autoscaler, key ""

   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Typ
e serviceType, String key) in c:\Home\Chris\Projects\CommonServiceLocator\main\M
icrosoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 53
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TSe
rvice]() in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices
.ServiceLocation\ServiceLocatorImplBase.cs:line 90
   at AutoScalingConsoleApplication.Program.Main(String[] args) 



here is the Default configuration used:

<configuration>
  <configSections>
    <section name="autoscalingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.Configuration.AutoscalingSettings, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=null" requirePermission="true" />
   
    <section name="typeRegistrationProvidersConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.TypeRegistrationProvidersConfigurationSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
 
  <autoscalingConfiguration dataPointsStoreAccount="DefaultEndpointsProtocol=https;AccountName=eendev;AccountKey=A/WxRODH/eJnBEY97djGZLOjlPGwqa8bfREhfujuTFtJd4fyzxlcXIABGUGZFDdgzBUEmZpe1XJM9jW1vwFZOg=="
    ruleEvaluationRate="00:01:00" loggerName="Source Logger" rulesStoreName="Local File Rules Store"
    serviceInformationStoreName="Local File Service Information Store">
   
    <rulesStores>
      <add name="Local File Rules Store" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.Rules.Configuration.LocalXmlFileRulesStore, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=null"
        filename="./RulesStore.xml" />
    </rulesStores>
    <serviceInformationStores>
      <add name="Local File Service Information Store" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.ServiceModel.Configuration.LocalXmlFileServiceInformationStore, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling, Version=5.0.1118.0, Culture=neutral, PublicKeyToken=null"
        filename="./ServiceInformationStore.xml" />
    </serviceInformationStores>
    <advancedOptions>
      <serviceManagementRequestTracker trackServiceManagementRequests="true"
        storageAccount="DefaultEndpointsProtocol=https;AccountName=eendev;AccountKey=A/WxRODH/eJnBEY97djGZLOjlPGwqa8bfREhfujuTFtJd4fyzxlcXIABGUGZFDdgzBUEmZpe1XJM9jW1vwFZOg==" />
      <executionLease useBlobExecutionLease="true" blobExecutionLeaseStorageAccount="DefaultEndpointsProtocol=https;AccountName=eendev;AccountKey=A/WxRODH/eJnBEY97djGZLOjlPGwqa8bfREhfujuTFtJd4fyzxlcXIABGUGZFDdgzBUEmZpe1XJM9jW1vwFZOg=="
        blobExecutionLeaseBlobContainerName="autoscaling-container-perf" />
    </advancedOptions>
  </autoscalingConfiguration>

This sample code is from ConsoleAutoscaler, which is part of Autoscale appliaction block. Please let me know what could be the possiable issue, thanks in advance..

Dec 22, 2011 at 9:16 PM

Can you paste the inner exception here? It should contain exactly what failed to build, so we can understand the issue better.

-Julian