forked from Azure/azure-functions-host
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding support for IWebJobsConfigurationStartup (Azure#5991)
- Loading branch information
Showing
21 changed files
with
801 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
src/WebJobs.Script/DependencyInjection/ExternalConfigurationStartupValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.Azure.WebJobs.Host; | ||
using Microsoft.Extensions.Configuration; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace Microsoft.Azure.WebJobs.Script.DependencyInjection | ||
{ | ||
internal class ExternalConfigurationStartupValidator | ||
{ | ||
private readonly IConfiguration _config; | ||
private readonly IFunctionMetadataManager _metadataManager; | ||
private readonly DefaultNameResolver _nameResolver; | ||
|
||
public ExternalConfigurationStartupValidator(IConfiguration config, IFunctionMetadataManager metadataManager) | ||
{ | ||
_config = config ?? throw new ArgumentNullException(nameof(config)); | ||
_metadataManager = metadataManager ?? throw new ArgumentNullException(nameof(metadataManager)); | ||
_nameResolver = new DefaultNameResolver(config); | ||
} | ||
|
||
/// <summary> | ||
/// Validates the current configuration against the original configuration. If any values for a trigger | ||
/// do not match, they are returned via the return value. | ||
/// </summary> | ||
/// <param name="originalConfig">The original configuration</param> | ||
/// <returns>A dictionary mapping function name to a list of the invalid values for that function.</returns> | ||
public IDictionary<string, IEnumerable<string>> Validate(IConfigurationRoot originalConfig) | ||
{ | ||
if (originalConfig == null) | ||
{ | ||
throw new ArgumentNullException(nameof(originalConfig)); | ||
} | ||
|
||
INameResolver originalNameResolver = new DefaultNameResolver(originalConfig); | ||
IDictionary<string, IEnumerable<string>> invalidValues = new Dictionary<string, IEnumerable<string>>(); | ||
|
||
var functions = _metadataManager.GetFunctionMetadata(); | ||
|
||
foreach (var function in functions) | ||
{ | ||
var trigger = function.Bindings.SingleOrDefault(b => b.IsTrigger); | ||
|
||
if (trigger == null) | ||
{ | ||
continue; | ||
} | ||
|
||
IList<string> invalidValuesForFunction = new List<string>(); | ||
|
||
// make sure none of the resolved values have changed for the trigger. | ||
foreach (KeyValuePair<string, JToken> property in trigger.Raw) | ||
{ | ||
string lookup = property.Value?.ToString(); | ||
|
||
if (lookup != null) | ||
{ | ||
string originalValue = originalConfig[lookup]; | ||
string newValue = _config[lookup]; | ||
if (originalValue != newValue) | ||
{ | ||
invalidValuesForFunction.Add(lookup); | ||
} | ||
else | ||
{ | ||
// It may be a binding expression like "%lookup%" | ||
originalNameResolver.TryResolveWholeString(lookup, out originalValue); | ||
_nameResolver.TryResolveWholeString(lookup, out newValue); | ||
|
||
if (originalValue != newValue) | ||
{ | ||
invalidValuesForFunction.Add(lookup); | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (invalidValuesForFunction.Any()) | ||
{ | ||
invalidValues[function.Name] = invalidValuesForFunction; | ||
} | ||
} | ||
|
||
return invalidValues; | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/WebJobs.Script/DependencyInjection/ExternalConfigurationStartupValidatorService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Microsoft.Azure.WebJobs.Script.DependencyInjection | ||
{ | ||
internal class ExternalConfigurationStartupValidatorService : IHostedService | ||
{ | ||
private readonly ExternalConfigurationStartupValidator _validator; | ||
private readonly IConfigurationRoot _originalConfig; | ||
private readonly IEnvironment _environment; | ||
private readonly ILogger<ExternalConfigurationStartupValidator> _logger; | ||
|
||
public ExternalConfigurationStartupValidatorService(ExternalConfigurationStartupValidator validator, IConfigurationRoot originalConfig, IEnvironment environment, ILogger<ExternalConfigurationStartupValidator> logger) | ||
{ | ||
_validator = validator ?? throw new ArgumentNullException(nameof(validator)); | ||
_originalConfig = originalConfig ?? throw new ArgumentNullException(nameof(originalConfig)); | ||
_environment = environment ?? throw new ArgumentNullException(nameof(environment)); | ||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||
} | ||
|
||
public Task StartAsync(CancellationToken cancellationToken) | ||
{ | ||
IDictionary<string, IEnumerable<string>> invalidValues = _validator.Validate(_originalConfig); | ||
|
||
if (invalidValues.Any()) | ||
{ | ||
StringBuilder sb = new StringBuilder(); | ||
sb.AppendLine("The Functions scale controller may not scale the following functions correctly because some configuration values were modified in an external startup class."); | ||
|
||
foreach (KeyValuePair<string, IEnumerable<string>> invalidValueMap in invalidValues) | ||
{ | ||
sb.AppendLine($" Function '{invalidValueMap.Key}' uses the modified key(s): {string.Join(", ", invalidValueMap.Value)}"); | ||
} | ||
|
||
if (_environment.IsCoreTools()) | ||
{ | ||
// We don't know where this will be deployed, so it may not matter, | ||
// but log this as a warning during development. | ||
_logger.LogWarning(sb.ToString()); | ||
} | ||
else | ||
{ | ||
throw new HostInitializationException(sb.ToString()); | ||
} | ||
} | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
public Task StopAsync(CancellationToken cancellationToken) | ||
{ | ||
return Task.CompletedTask; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.