Skip to content

Commit

Permalink
Merge pull request #243 from gabikliot/Update-Provider-Configuration
Browse files Browse the repository at this point in the history
More programmatic support to provider configuration.
  • Loading branch information
sergeybykov committed Mar 19, 2015
2 parents 55a9c3b + b6c07f5 commit 7ccdc74
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 92 deletions.
111 changes: 51 additions & 60 deletions Samples/AzureWebSample/OrleansAzureSilos/WorkerRole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public override void Run()
config.StandardLoad();

// First example of how to configure an existing provider
ConfigureExistingStorageProvider(config);
ConfigureNewStorageProvider(config);
ConfigureNewBootstrapProvider(config);
//ConfigureExistingStorageProvider(config);
//ConfigureNewStorageProvider(config);
//ConfigureNewBootstrapProvider(config);

// It is IMPORTANT to start the silo not in OnStart but in Run.
// Azure may not have the firewalls open yet (on the remote silos) at the OnStart phase.
Expand Down Expand Up @@ -150,90 +150,81 @@ private static void SetupEnvironmentChangeHandlers()
// Below is an example of how to set the storage key in the ProviderConfiguration and how to add a new custom configuration property.
private void ConfigureExistingStorageProvider(ClusterConfiguration config)
{
ProviderCategoryConfiguration storageConfiguration;
if (config.Globals.ProviderConfigurations.TryGetValue(STORAGE_KEY, out storageConfiguration))
IProviderConfiguration storageProvider = null;

const string myProviderFullTypeName = "Orleans.Storage.AzureTableStorage"; // Alternatively, can be something like typeof(AzureTableStorage).FullName
const string myProviderName = "AzureStore"; // what ever arbitrary name you want to give to your provider
if (config.Globals.TryGetProviderConfiguration(myProviderFullTypeName, myProviderName, out storageProvider))
{
// Modify the specific "AzureStore" provider
IProviderConfiguration iProviderConfig = null;
if (storageConfiguration.Providers.TryGetValue("AzureStore", out iProviderConfig))
{
ProviderConfiguration storageProvider = iProviderConfig as ProviderConfiguration;
storageProvider.SetProperty("MyCustomProperty1", "MyCustomPropertyValue1");
}
// provider configuration already exists, modify it.
string connectionString = RoleEnvironment.GetConfigurationSettingValue(DATA_CONNECTION_STRING_KEY);
storageProvider.SetProperty(DATA_CONNECTION_STRING_KEY, connectionString);
storageProvider.SetProperty("MyCustomProperty1", "MyCustomPropertyValue1");
}
else
{
// provider configuration does not exists, add a new one.
var properties = new Dictionary<string, string>();
string connectionString = RoleEnvironment.GetConfigurationSettingValue(DATA_CONNECTION_STRING_KEY);
properties.Add(DATA_CONNECTION_STRING_KEY, connectionString);
properties.Add("MyCustomProperty2", "MyCustomPropertyValue2");

config.Globals.RegisterStorageProvider(myProviderFullTypeName, myProviderName, properties);
}

// Alternatively, find all storage providers and modify them as necessary
foreach (ProviderConfiguration providerConfig in storageConfiguration.Providers.Values.Where(provider => provider is ProviderConfiguration).Cast<ProviderConfiguration>())
// Alternatively, find all storage providers and modify them as necessary
foreach (IProviderConfiguration providerConfig in config.Globals.GetAllProviderConfigurations())//storageConfiguration.Providers.Values.Where(provider => provider is ProviderConfiguration).Cast<ProviderConfiguration>())
{
if (providerConfig.Type.Equals(myProviderFullTypeName))
{
string connectionString = RoleEnvironment.GetConfigurationSettingValue(DATA_CONNECTION_STRING_KEY);
providerConfig.SetProperty(DATA_CONNECTION_STRING_KEY, connectionString);
providerConfig.SetProperty("MyCustomProperty2", "MyCustomPropertyValue2");

providerConfig.SetProperty("MyCustomProperty3", "MyCustomPropertyValue3");
}

// Once silo starts you can see that it prints in the log:
// Providers:
// StorageProviders:
// Name=AzureStore, Type=Orleans.Storage.AzureTableStorage, Properties=[DataConnectionString, MyCustomProperty, MyCustomProperty2]
}

// Once silo starts you can see that it prints in the log:
// Providers:
// StorageProviders:
// Name=AzureStore, Type=Orleans.Storage.AzureTableStorage, Properties=[DataConnectionString, MyCustomProperty, MyCustomProperty1, MyCustomProperty3]
}

// Below is an example of how to define a full configuration for a new storage provider that is not already specified in the config file.
private void ConfigureNewStorageProvider(ClusterConfiguration config)
{
ProviderCategoryConfiguration categoryConfiguration;
if (!config.Globals.ProviderConfigurations.TryGetValue(STORAGE_KEY, out categoryConfiguration))
{
categoryConfiguration = new ProviderCategoryConfiguration()
{
Name = STORAGE_KEY,
Providers = new Dictionary<string, IProviderConfiguration>()
};
config.Globals.ProviderConfigurations.Add(STORAGE_KEY, categoryConfiguration);
}

string myProviderName = "MyNewAzureStoreProvider"; // what ever arbitrary name you want to give to your provider
// Alternatively, the 2nd argument, type, can be something like typeof(EventStoreInitBootstrapProvider).FullName
ProviderConfiguration providerConfig = new ProviderConfiguration(new Dictionary<string, string>(), "Orleans.Storage.AzureTableStorage", myProviderName);
categoryConfiguration.Providers.Add(myProviderName, providerConfig);
const string myProviderFullTypeName = "Orleans.Storage.AzureTableStorage"; // Alternatively, can be something like typeof(AzureTableStorage).FullName
const string myProviderName = "MyNewAzureStoreProvider"; // what ever arbitrary name you want to give to your provider

var properties = new Dictionary<string, string>();
string connectionString = RoleEnvironment.GetConfigurationSettingValue(DATA_CONNECTION_STRING_KEY);
providerConfig.SetProperty(DATA_CONNECTION_STRING_KEY, connectionString);
providerConfig.SetProperty("MyCustomProperty3", "MyCustomPropertyValue3");
properties.Add(DATA_CONNECTION_STRING_KEY, connectionString);
properties.Add("MyCustomProperty3", "MyCustomPropertyValue3");

config.Globals.RegisterStorageProvider(myProviderFullTypeName, myProviderName, properties);

// Once silo starts you can see that it prints in the log:
// Providers:
// StorageProviders:
// Name=MyNewAzureStoreProvider, Type=Orleans.Storage.AzureTableStorage, Properties=[DataConnectionString, MyCustomProperty3]
// Providers:
// StorageProviders:
// Name=MyNewAzureStoreProvider, Type=Orleans.Storage.AzureTableStorage, Properties=[DataConnectionString, MyCustomProperty3]
}

// Below is an example of how to define a full configuration for a new Bootstrap provider that is not already specified in the config file.
private void ConfigureNewBootstrapProvider(ClusterConfiguration config)
{
ProviderCategoryConfiguration categoryConfiguration;
if (!config.Globals.ProviderConfigurations.TryGetValue(BOOTSTRAP_KEY, out categoryConfiguration))
{
categoryConfiguration = new ProviderCategoryConfiguration()
{
Name = BOOTSTRAP_KEY,
Providers = new Dictionary<string, IProviderConfiguration>()
};
config.Globals.ProviderConfigurations.Add(BOOTSTRAP_KEY, categoryConfiguration);
}

string myProviderName = "MyNewBootstrapProvider"; // what ever arbitrary name you want to give to your provider
// Alternatively, the 2nd argument, type, can be something like typeof(EventStoreInitBootstrapProvider).FullName
ProviderConfiguration providerConfig = new ProviderConfiguration(new Dictionary<string, string>(), "FullNameSpace.NewBootstrapProviderType", myProviderName);
//categoryConfiguration.Providers.Add(myProviderName, providerConfig);
const string myProviderFullTypeName = "FullNameSpace.NewBootstrapProviderType"; // Alternatively, can be something like typeof(EventStoreInitBootstrapProvider).FullName
const string myProviderName = "MyNewBootstrapProvider"; // what ever arbitrary name you want to give to your provider
var properties = new Dictionary<string, string>();
config.Globals.RegisterBootstrapProvider(myProviderFullTypeName, myProviderName, properties);

// The last line, categoryConfiguration.Providers.Add, is commented out because the assembly with "FullNameSpace.NewBootstrapProviderType" is not added to the project,
// The last line, config.Globals.RegisterBootstrapProvider, is commented out because the assembly with "FullNameSpace.NewBootstrapProviderType" is not added to the project,
// this the silo will fail to load the new bootstrap provider upon startup.
// !!!!!!!!!! Provider of type FullNameSpace.NewBootstrapProviderType name MyNewBootstrapProvider was not loaded.
// Once you add your new provider to the project, uncommnet this line.

// Once silo starts you can see that it prints in the log:
// Providers:
// BootstrapProviders:
// Name=MyNewBootstrapProvider, Type=FullNameSpace.NewBootstrapProviderType, Properties=[]
// Providers:
// BootstrapProviders:
// Name=MyNewBootstrapProvider, Type=FullNameSpace.NewBootstrapProviderType, Properties=[]
}
}
}
33 changes: 27 additions & 6 deletions src/Orleans/Configuration/ClientConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The above copyright notice and this permission notice shall be included in all c
using System.Net.Sockets;
using System.Text;
using System.Xml;
using Orleans.Providers;

namespace Orleans.Runtime.Configuration
{
Expand Down Expand Up @@ -308,17 +309,16 @@ internal void LoadFromXml(XmlElement root)
default:
if (child.LocalName.EndsWith("Providers", StringComparison.Ordinal))
{
var providerConfig = new ProviderCategoryConfiguration();
providerConfig.Load(child);
var providerCategory = ProviderCategoryConfiguration.Load(child);

if (ProviderConfigurations.ContainsKey(providerConfig.Name))
if (ProviderConfigurations.ContainsKey(providerCategory.Name))
{
var existingProviderConfig = ProviderConfigurations[providerConfig.Name];
existingProviderConfig.Merge(providerConfig);
var existingCategory = ProviderConfigurations[providerCategory.Name];
existingCategory.Merge(providerCategory);
}
else
{
ProviderConfigurations.Add(providerConfig.Name, providerConfig);
ProviderConfigurations.Add(providerCategory.Name, providerCategory);
}
}
break;
Expand Down Expand Up @@ -376,6 +376,27 @@ public void RegisterStreamProvider(string providerTypeFullName, string providerN
ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STREAM_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties);
}

/// <summary>
/// Retrieves an existing provider configuration
/// </summary>
/// <param name="providerTypeFullName">Full name of the stream provider type</param>
/// <param name="providerName">Name of the stream provider</param>
/// <param name="config">The provider configuration, if exists</param>
/// <returns>True if a configuration for this provider already exists, false otherwise.</returns>
public bool TryGetProviderConfiguration(string providerTypeFullName, string providerName, out IProviderConfiguration config)
{
return ProviderConfigurationUtility.TryGetProviderConfiguration(ProviderConfigurations, providerTypeFullName, providerName, out config);
}

/// <summary>
/// Retrieves an enumeration of all currently configured provider configurations.
/// </summary>
/// <returns>An enumeration of all currently configured provider configurations.</returns>
public IEnumerable<IProviderConfiguration> GetAllProviderConfigurations()
{
return ProviderConfigurationUtility.GetAllProviderConfigurations(ProviderConfigurations);
}

/// <summary>
/// This method may be called by the client host or test host to tweak a provider configuration after it has been already loaded.
/// Its is optional and should NOT be automaticaly called by the runtime.
Expand Down
32 changes: 26 additions & 6 deletions src/Orleans/Configuration/GlobalConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -671,17 +671,16 @@ internal override void Load(XmlElement root)
default:
if (child.LocalName.EndsWith("Providers", StringComparison.Ordinal))
{
var providerConfig = new ProviderCategoryConfiguration();
providerConfig.Load(child);
var providerCategory = ProviderCategoryConfiguration.Load(child);

if (ProviderConfigurations.ContainsKey(providerConfig.Name))
if (ProviderConfigurations.ContainsKey(providerCategory.Name))
{
var existingProviderConfig = ProviderConfigurations[providerConfig.Name];
existingProviderConfig.Merge(providerConfig);
var existingCategory = ProviderConfigurations[providerCategory.Name];
existingCategory.Merge(providerCategory);
}
else
{
ProviderConfigurations.Add(providerConfig.Name, providerConfig);
ProviderConfigurations.Add(providerCategory.Name, providerCategory);
}
}
break;
Expand Down Expand Up @@ -772,5 +771,26 @@ public void RegisterStorageProvider(string providerTypeFullName, string provider
{
ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STORAGE_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties);
}

/// <summary>
/// Retrieves an existing provider configuration
/// </summary>
/// <param name="providerTypeFullName">Full name of the stream provider type</param>
/// <param name="providerName">Name of the stream provider</param>
/// <param name="config">The provider configuration, if exists</param>
/// <returns>True if a configuration for this provider already exists, false otherwise.</returns>
public bool TryGetProviderConfiguration(string providerTypeFullName, string providerName, out IProviderConfiguration config)
{
return ProviderConfigurationUtility.TryGetProviderConfiguration(ProviderConfigurations, providerTypeFullName, providerName, out config);
}

/// <summary>
/// Retrieves an enumeration of all currently configured provider configurations.
/// </summary>
/// <returns>An enumeration of all currently configured provider configurations.</returns>
public IEnumerable<IProviderConfiguration> GetAllProviderConfigurations()
{
return ProviderConfigurationUtility.GetAllProviderConfigurations(ProviderConfigurations);
}
}
}
Loading

0 comments on commit 7ccdc74

Please sign in to comment.