Skip to content

Commit 3499952

Browse files
[Cherrypick] [pack] Sourcing configuration from WebHost and Active JobHost for Storage operations (#7506)
1 parent bb5f9e0 commit 3499952

File tree

19 files changed

+799
-28
lines changed

19 files changed

+799
-28
lines changed

src/WebJobs.Script.WebHost/Security/KeyManagement/DefaultSecretManagerProvider.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ public DefaultSecretManagerProvider(IOptionsMonitor<ScriptApplicationHostOptions
6161
internal ISecretsRepository CreateSecretsRepository()
6262
{
6363
string secretStorageType = Environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageType);
64-
var storageConnection = _configuration.GetWebJobsConnectionStringSection(ConnectionStringNames.Storage);
6564
string secretStorageSas = _environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageSas);
6665
if (secretStorageType != null && secretStorageType.Equals(FileStorage, StringComparison.OrdinalIgnoreCase))
6766
{
@@ -83,7 +82,7 @@ internal ISecretsRepository CreateSecretsRepository()
8382
string siteSlotName = _environment.GetAzureWebsiteUniqueSlotName() ?? _hostIdProvider.GetHostIdAsync(CancellationToken.None).GetAwaiter().GetResult();
8483
return new BlobStorageSasSecretsRepository(Path.Combine(_options.CurrentValue.SecretsPath, "Sentinels"), secretStorageSas, siteSlotName, _loggerFactory.CreateLogger<BlobStorageSasSecretsRepository>(), _environment, _azureStorageProvider);
8584
}
86-
else if (storageConnection.Exists())
85+
else if (_azureStorageProvider.ConnectionExists(ConnectionStringNames.Storage))
8786
{
8887
string siteSlotName = _environment.GetAzureWebsiteUniqueSlotName() ?? _hostIdProvider.GetHostIdAsync(CancellationToken.None).GetAwaiter().GetResult();
8988
return new BlobStorageSecretsRepository(Path.Combine(_options.CurrentValue.SecretsPath, "Sentinels"), ConnectionStringNames.Storage, siteSlotName, _loggerFactory.CreateLogger<BlobStorageSecretsRepository>(), _environment, _azureStorageProvider);

src/WebJobs.Script.WebHost/WebJobsScriptHostService.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ public WebJobsScriptHostService(IOptionsMonitor<ScriptApplicationHostOptions> ap
9595

9696
public event EventHandler HostInitializing;
9797

98+
public event EventHandler<ActiveHostChangedEventArgs> ActiveHostChanged;
99+
98100
[Flags]
99101
private enum JobHostStartupMode
100102
{
@@ -118,7 +120,11 @@ private IHost ActiveHost
118120
set
119121
{
120122
_logger?.ActiveHostChanging(GetHostInstanceId(_host), GetHostInstanceId(value));
123+
124+
var previousHost = _host;
121125
_host = value;
126+
127+
OnActiveHostChanged(previousHost, _host);
122128
}
123129
}
124130

@@ -530,6 +536,11 @@ private void OnHostInitializing(object sender, EventArgs e)
530536
HostInitializing?.Invoke(sender, e);
531537
}
532538

539+
private void OnActiveHostChanged(IHost previousHost, IHost newHost)
540+
{
541+
ActiveHostChanged?.Invoke(this, new ActiveHostChangedEventArgs(previousHost, _host));
542+
}
543+
533544
/// <summary>
534545
/// Called after the host has been fully initialized, but before it
535546
/// has been started.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
5+
using Microsoft.Extensions.Hosting;
6+
7+
namespace Microsoft.Azure.WebJobs.Script
8+
{
9+
public sealed class ActiveHostChangedEventArgs : EventArgs
10+
{
11+
public ActiveHostChangedEventArgs(IHost previousHost, IHost newHost)
12+
{
13+
PreviousHost = previousHost;
14+
NewHost = newHost;
15+
}
16+
17+
public IHost NewHost { get; }
18+
19+
public IHost PreviousHost { get; }
20+
}
21+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using Microsoft.Extensions.Configuration;
7+
8+
namespace Microsoft.Azure.WebJobs.Script.Configuration
9+
{
10+
public class ActiveHostConfigurationSource : IConfigurationSource
11+
{
12+
private readonly IScriptHostManager _scriptHostManager;
13+
14+
public ActiveHostConfigurationSource(IScriptHostManager scriptHostManager)
15+
{
16+
_scriptHostManager = scriptHostManager;
17+
}
18+
19+
public IConfigurationProvider Build(IConfigurationBuilder builder)
20+
{
21+
return new ActiveHostConfigurationProvider(_scriptHostManager);
22+
}
23+
24+
private class ActiveHostConfigurationProvider : ConfigurationProvider, IDisposable
25+
{
26+
private readonly IScriptHostManager _scriptHostManager;
27+
private IDisposable _changeTokenRegistration;
28+
29+
public ActiveHostConfigurationProvider(IScriptHostManager scriptHostManager)
30+
{
31+
_scriptHostManager = scriptHostManager ?? throw new ArgumentNullException(nameof(scriptHostManager));
32+
scriptHostManager.ActiveHostChanged += HandleActiveHostChange;
33+
}
34+
35+
public override void Load()
36+
{
37+
if ((_scriptHostManager as IServiceProvider)?.GetService(typeof(IConfiguration)) is IConfigurationRoot activeHostConfiguration)
38+
{
39+
Data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
40+
foreach (var kvp in activeHostConfiguration.AsEnumerable())
41+
{
42+
if (!Data.ContainsKey(kvp.Key))
43+
{
44+
Data[kvp.Key] = kvp.Value;
45+
}
46+
}
47+
48+
_changeTokenRegistration?.Dispose();
49+
_changeTokenRegistration = activeHostConfiguration.GetReloadToken().RegisterChangeCallback(_ => Load(), null);
50+
OnReload();
51+
}
52+
}
53+
54+
private void HandleActiveHostChange(object sender, ActiveHostChangedEventArgs e)
55+
{
56+
Load();
57+
}
58+
59+
public void Dispose()
60+
{
61+
_changeTokenRegistration?.Dispose();
62+
_scriptHostManager.ActiveHostChanged -= HandleActiveHostChange;
63+
}
64+
}
65+
}
66+
}

src/WebJobs.Script/Host/IScriptHostManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public interface IScriptHostManager
1414
/// </summary>
1515
event EventHandler HostInitializing;
1616

17+
/// <summary>
18+
/// Evewnt raised when the active host managed by this instance changes.
19+
/// </summary>
20+
event EventHandler<ActiveHostChangedEventArgs> ActiveHostChanged;
21+
1722
ScriptHostState State { get; }
1823

1924
/// <summary>

src/WebJobs.Script/ScriptConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ public static class ScriptConstants
112112
public const string FeatureFlagEnableEnhancedScopes = "EnableEnhancedScopes";
113113
public const string FeatureFlagDisableDevInDebug = "DisableDevModeInDebug";
114114
public const string FeatureFlagEnableDiagnosticEventLogging = "EnableDiagnosticEventLogging";
115+
public const string FeatureFlagDisableMergedWebHostScriptHostConfiguration = "DisableMergedConfiguration";
115116

116117
public const string AdminJwtValidAudienceFormat = "https://{0}.azurewebsites.net/azurefunctions";
117118
public const string AdminJwtValidIssuerFormat = "https://{0}.scm.azurewebsites.net";

src/WebJobs.Script/ScriptHostBuilderExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,6 @@ private static IDistributedLockManager GetBlobLockManager(IServiceProvider provi
466466
{
467467
// If there is an error getting the container client,
468468
// register an InMemoryDistributedLockManager.
469-
// This signals a failed validation in connection configuration (i.e. could not create the storage client).
470469
logger.LogDebug("Using InMemoryDistributedLockManager in Functions Host.");
471470
return new InMemoryDistributedLockManager();
472471
}

src/WebJobs.Script/StorageProvider/AzureStorageProvider.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
using System;
55
using Azure.Storage.Blobs;
6+
using Microsoft.Azure.WebJobs.Script.Config;
7+
using Microsoft.Azure.WebJobs.Script.Configuration;
8+
using Microsoft.Azure.WebJobs.Script.Extensions;
69
using Microsoft.Azure.WebJobs.Script.StorageProvider;
710
using Microsoft.Extensions.Configuration;
811
using Microsoft.Extensions.Logging;
@@ -18,16 +21,39 @@ namespace Microsoft.Azure.WebJobs.Script
1821
internal class AzureStorageProvider : IAzureStorageProvider
1922
{
2023
private readonly BlobServiceClientProvider _blobServiceClientProvider;
21-
private readonly IConfiguration _configuration;
22-
private readonly ILogger _logger;
2324
private IOptionsMonitor<JobHostInternalStorageOptions> _storageOptions;
25+
private IConfiguration _configuration;
26+
private ILogger _logger;
2427

25-
public AzureStorageProvider(IConfiguration configuration, BlobServiceClientProvider blobServiceClientProvider, IOptionsMonitor<JobHostInternalStorageOptions> options, ILogger<AzureStorageProvider> logger)
28+
public AzureStorageProvider(IScriptHostManager scriptHostManager, IConfiguration configuration, BlobServiceClientProvider blobServiceClientProvider, IOptionsMonitor<JobHostInternalStorageOptions> options, ILogger<AzureStorageProvider> logger)
2629
{
2730
_blobServiceClientProvider = blobServiceClientProvider;
28-
_configuration = configuration;
2931
_storageOptions = options;
3032
_logger = logger;
33+
34+
if (FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagDisableMergedWebHostScriptHostConfiguration))
35+
{
36+
_configuration = configuration;
37+
}
38+
else
39+
{
40+
_ = scriptHostManager ?? throw new ArgumentNullException(nameof(scriptHostManager));
41+
_configuration = new ConfigurationBuilder()
42+
.AddConfiguration(configuration)
43+
.Add(new ActiveHostConfigurationSource(scriptHostManager))
44+
.Build();
45+
}
46+
}
47+
48+
/// <summary>
49+
/// Checks if a BlobServiceClient can be created (indicates the specified connection can be parsed)
50+
/// </summary>
51+
/// <param name="connection">connection to use for the BlobServiceClient</param>
52+
/// <returns>true if successful; false otherwise</returns>
53+
public bool ConnectionExists(string connection)
54+
{
55+
var section = _configuration.GetWebJobsConnectionStringSection(connection);
56+
return section != null && section.Exists();
3157
}
3258

3359
/// <summary>
@@ -52,7 +78,7 @@ public virtual bool TryGetBlobServiceClientFromConnectionString(out BlobServiceC
5278
public virtual bool TryGetBlobServiceClientFromConnection(out BlobServiceClient client, string connection = null)
5379
{
5480
var connectionToUse = connection ?? ConnectionStringNames.Storage;
55-
return _blobServiceClientProvider.TryGet(connectionToUse, out client);
81+
return _blobServiceClientProvider.TryGet(connectionToUse, _configuration, out client);
5682
}
5783

5884
public virtual BlobContainerClient GetBlobContainerClient()

src/WebJobs.Script/StorageProvider/BlobServiceClientProvider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ namespace Microsoft.Azure.WebJobs.Script.StorageProvider
1616
/// </summary>
1717
internal class BlobServiceClientProvider : StorageClientProvider<BlobServiceClient, BlobClientOptions>
1818
{
19-
public BlobServiceClientProvider(IConfiguration configuration, AzureComponentFactory componentFactory, AzureEventSourceLogForwarder logForwarder, ILogger<BlobServiceClientProvider> logger)
20-
: base(configuration, componentFactory, logForwarder, logger) { }
19+
public BlobServiceClientProvider(AzureComponentFactory componentFactory, AzureEventSourceLogForwarder logForwarder, ILogger<BlobServiceClientProvider> logger)
20+
: base(componentFactory, logForwarder, logger) { }
2121

2222
/// <inheritdoc/>
2323
protected override string ServiceUriSubDomain

src/WebJobs.Script/StorageProvider/IAzureStorageProvider.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using Azure.Storage.Blobs;
5+
using Microsoft.Extensions.Configuration;
56

67
namespace Microsoft.Azure.WebJobs.Script
78
{
@@ -11,6 +12,8 @@ namespace Microsoft.Azure.WebJobs.Script
1112
/// </summary>
1213
public interface IAzureStorageProvider
1314
{
15+
bool ConnectionExists(string connection);
16+
1417
bool TryGetBlobServiceClientFromConnectionString(out BlobServiceClient client, string connectionString);
1518

1619
bool TryGetBlobServiceClientFromConnection(out BlobServiceClient client, string connection);

0 commit comments

Comments
 (0)