1
- // Copyright (c) .NET Foundation. All rights reserved.
1
+ // Copyright (c) .NET Foundation. All rights reserved.
2
2
// Licensed under the MIT License. See License.txt in the project root for license information.
3
3
4
4
using System ;
10
10
using Microsoft . Azure . WebJobs . Logging ;
11
11
using Microsoft . Azure . WebJobs . Script . Diagnostics ;
12
12
using Microsoft . Azure . WebJobs . Script . Diagnostics . Extensions ;
13
- using Microsoft . Azure . WebJobs . Script . Workers . Rpc ;
14
13
using Microsoft . Extensions . Configuration ;
15
14
using Microsoft . Extensions . Logging ;
16
15
using Newtonsoft . Json ;
@@ -23,22 +22,23 @@ public class HostJsonFileConfigurationSource : IConfigurationSource
23
22
private readonly ILogger _logger ;
24
23
private readonly IMetricsLogger _metricsLogger ;
25
24
26
- public HostJsonFileConfigurationSource ( ScriptApplicationHostOptions applicationHostOptions , IEnvironment environment , ILoggerFactory loggerFactory , IMetricsLogger metricsLogger )
25
+ public HostJsonFileConfigurationSource (
26
+ HostJsonFileConfigurationOptions options ,
27
+ ILoggerFactory loggerFactory ,
28
+ IMetricsLogger metricsLogger )
27
29
{
28
- if ( loggerFactory == null )
29
- {
30
- throw new ArgumentNullException ( nameof ( loggerFactory ) ) ;
31
- }
30
+ ArgumentNullException . ThrowIfNull ( options ) ;
31
+ ArgumentNullException . ThrowIfNull ( loggerFactory ) ;
32
+ ArgumentNullException . ThrowIfNull ( metricsLogger ) ;
32
33
33
- HostOptions = applicationHostOptions ;
34
- Environment = environment ;
35
- _metricsLogger = metricsLogger ;
34
+ Options = options ;
36
35
_logger = loggerFactory . CreateLogger ( LogCategories . Startup ) ;
36
+ _metricsLogger = metricsLogger ;
37
37
}
38
38
39
- public ScriptApplicationHostOptions HostOptions { get ; }
39
+ private HostJsonFileConfigurationOptions Options { get ; }
40
40
41
- public IEnvironment Environment { get ; }
41
+ private ScriptApplicationHostOptions HostOptions => Options . Host ;
42
42
43
43
public IConfigurationProvider Build ( IConfigurationBuilder builder )
44
44
{
@@ -47,30 +47,41 @@ public IConfigurationProvider Build(IConfigurationBuilder builder)
47
47
48
48
public class HostJsonFileConfigurationProvider : ConfigurationProvider
49
49
{
50
- private static readonly string [ ] WellKnownHostJsonProperties = new [ ]
51
- {
50
+ private static readonly string [ ] WellKnownHostJsonProperties =
51
+ [
52
52
"version" , "functionTimeout" , "retry" , "functions" , "http" , "watchDirectories" , "watchFiles" , "queues" , "serviceBus" ,
53
53
"eventHub" , "singleton" , "logging" , "aggregator" , "healthMonitor" , "extensionBundle" , "managedDependencies" ,
54
54
"customHandler" , "httpWorker" , "extensions" , "concurrency" , "telemetryMode" , ConfigurationSectionNames . SendCanceledInvocationsToWorker ,
55
55
ConfigurationSectionNames . MetadataProviderTimeout , "isDefaultHostConfig"
56
- } ;
56
+ ] ;
57
57
58
58
private readonly HostJsonFileConfigurationSource _configurationSource ;
59
- private readonly Stack < string > _path ;
59
+ private readonly Stack < string > _path = new ( ) ;
60
60
private readonly ILogger _logger ;
61
61
private readonly IMetricsLogger _metricsLogger ;
62
62
63
- public HostJsonFileConfigurationProvider ( HostJsonFileConfigurationSource configurationSource , ILogger logger , IMetricsLogger metricsLogger )
63
+ public HostJsonFileConfigurationProvider (
64
+ HostJsonFileConfigurationSource configurationSource , ILogger logger , IMetricsLogger metricsLogger )
64
65
{
65
66
_configurationSource = configurationSource ;
66
- _path = new Stack < string > ( ) ;
67
67
_logger = logger ;
68
68
_metricsLogger = metricsLogger ;
69
69
}
70
70
71
+ private HostJsonFileConfigurationOptions Options => _configurationSource . Options ;
72
+
71
73
public override void Load ( )
72
74
{
73
75
JObject hostJson = LoadHostConfigurationFile ( ) ;
76
+
77
+ // Apply profile settings first, so that they can be overridden by host.json settings.
78
+ HostConfigurationProfile profile = GetConfigProfile ( hostJson ) ;
79
+ _logger . LogDebug ( "Loading host configuration profile '{profileName}'." , profile . Name ) ;
80
+ foreach ( ( string key , string value ) in profile . Configuration )
81
+ {
82
+ Data [ ConfigurationPath . Combine ( ConfigurationSectionNames . JobHost , key ) ] = value ;
83
+ }
84
+
74
85
ProcessObject ( hostJson ) ;
75
86
}
76
87
@@ -141,9 +152,7 @@ private JObject LoadHostConfigurationFile()
141
152
// to the startup logger until we've read configuration settings and can create the real logger.
142
153
// The "startup" logger is used in this class for startup related logs. The public logger is used
143
154
// for all other logging after startup.
144
-
145
- ScriptApplicationHostOptions options = _configurationSource . HostOptions ;
146
- string hostFilePath = Path . Combine ( options . ScriptPath , ScriptConstants . HostMetadataFileName ) ;
155
+ string hostFilePath = Path . Combine ( Options . Host . ScriptPath , ScriptConstants . HostMetadataFileName ) ;
147
156
JObject hostConfigObject = LoadHostConfig ( hostFilePath ) ;
148
157
hostConfigObject = InitializeHostConfig ( hostFilePath , hostConfigObject ) ;
149
158
@@ -192,10 +201,11 @@ private JObject InitializeHostConfig(string hostJsonPath, JObject hostConfigObje
192
201
throw new HostConfigurationException ( errorMsg . ToString ( ) ) ;
193
202
}
194
203
}
204
+
195
205
return hostConfigObject ;
196
206
}
197
207
198
- internal JObject LoadHostConfig ( string configFilePath )
208
+ private JObject LoadHostConfig ( string configFilePath )
199
209
{
200
210
using ( _metricsLogger . LatencyEvent ( MetricEventNames . LoadHostConfiguration ) )
201
211
{
@@ -227,11 +237,11 @@ internal JObject LoadHostConfig(string configFilePath)
227
237
// So a newly created function app from the portal would have no host.json. In that case we need to
228
238
// create a new function app with host.json that includes a matching extension bundle based on the app kind.
229
239
hostConfigObject = GetDefaultHostConfigObject ( ) ;
230
- string bundleId = _configurationSource . Environment . IsLogicApp ( ) ?
240
+ string bundleId = Options . IsLogicApp ?
231
241
ScriptConstants . WorkFlowExtensionBundleId :
232
242
ScriptConstants . DefaultExtensionBundleId ;
233
243
234
- string bundleVersion = _configurationSource . Environment . IsLogicApp ( ) ?
244
+ string bundleVersion = Options . IsLogicApp ?
235
245
ScriptConstants . LogicAppDefaultExtensionBundleVersion :
236
246
ScriptConstants . DefaultExtensionBundleVersion ;
237
247
@@ -248,15 +258,29 @@ private JObject GetDefaultHostConfigObject()
248
258
{
249
259
// isDefaultHostConfig is used to determine if the host.json file was created by the system
250
260
var hostJsonJObj = JObject . Parse ( "{'version': '2.0', 'isDefaultHostConfig': true}" ) ;
251
- if ( string . Equals ( _configurationSource . Environment . GetEnvironmentVariable ( RpcWorkerConstants . FunctionWorkerRuntimeSettingName ) , "powershell" , StringComparison . InvariantCultureIgnoreCase )
252
- && ! _configurationSource . HostOptions . IsFileSystemReadOnly )
261
+ if ( string . Equals ( Options . WorkerRuntime , "powershell" , StringComparison . InvariantCultureIgnoreCase )
262
+ && ! Options . Host . IsFileSystemReadOnly )
253
263
{
254
264
hostJsonJObj . Add ( "managedDependency" , JToken . Parse ( "{'Enabled': true}" ) ) ;
255
265
}
256
266
257
267
return hostJsonJObj ;
258
268
}
259
269
270
+ private HostConfigurationProfile GetConfigProfile ( JObject hostFile )
271
+ {
272
+ ArgumentNullException . ThrowIfNull ( hostFile ) ;
273
+
274
+ try
275
+ {
276
+ return Options . GetConfigProfile ( hostFile ) ;
277
+ }
278
+ catch ( NotSupportedException ex )
279
+ {
280
+ throw new HostConfigurationException ( ex . Message , ex ) ;
281
+ }
282
+ }
283
+
260
284
private void TryWriteHostJson ( string filePath , JObject content )
261
285
{
262
286
if ( ! _configurationSource . HostOptions . IsFileSystemReadOnly )
@@ -278,7 +302,7 @@ private void TryWriteHostJson(string filePath, JObject content)
278
302
279
303
private JObject TryAddBundleConfiguration ( JObject content , string bundleId , string bundleVersion )
280
304
{
281
- if ( ! _configurationSource . HostOptions . IsFileSystemReadOnly )
305
+ if ( ! Options . Host . IsFileSystemReadOnly )
282
306
{
283
307
string bundleConfiguration = "{ 'id': '" + bundleId + "', 'version': '" + bundleVersion + "'}" ;
284
308
content . Add ( "extensionBundle" , JToken . Parse ( bundleConfiguration ) ) ;
0 commit comments