13
13
using Microsoft . Azure . WebJobs . Script . Description ;
14
14
using Microsoft . Azure . WebJobs . Script . Management . Models ;
15
15
using Microsoft . Azure . WebJobs . Script . WebHost . Extensions ;
16
- using Microsoft . Azure . WebJobs . Script . WebHost . Helpers ;
17
16
using Microsoft . Azure . WebJobs . Script . WebHost . Security ;
18
17
using Microsoft . Extensions . Logging ;
19
18
using Newtonsoft . Json ;
@@ -23,6 +22,12 @@ namespace Microsoft.Azure.WebJobs.Script.WebHost.Management
23
22
{
24
23
public class WebFunctionsManager : IWebFunctionsManager
25
24
{
25
+ private const string HubName = "HubName" ;
26
+ private const string TaskHubName = "taskHubName" ;
27
+ private const string Connection = "connection" ;
28
+ private const string DurableTaskStorageConnectionName = "azureStorageConnectionStringName" ;
29
+ private const string DurableTask = "durableTask" ;
30
+
26
31
private readonly ScriptHostConfiguration _config ;
27
32
private readonly ILogger _logger ;
28
33
private readonly HttpClient _client ;
@@ -167,7 +172,7 @@ await functionMetadata
167
172
/// <returns>(success, error)</returns>
168
173
public async Task < ( bool success , string error ) > TrySyncTriggers ( )
169
174
{
170
- var durableTaskHubName = await GetDurableTaskHubName ( ) ;
175
+ var durableTaskConfig = await ReadDurableTaskConfig ( ) ;
171
176
var functionsTriggers = ( await GetFunctionsMetadata ( )
172
177
. Select ( f => f . ToFunctionTrigger ( _config ) )
173
178
. WhenAll ( ) )
@@ -176,11 +181,19 @@ await functionMetadata
176
181
{
177
182
// if we have a durableTask hub name and the function trigger is either orchestrationTrigger OR activityTrigger,
178
183
// add a property "taskHubName" with durable task hub name.
179
- if ( durableTaskHubName != null
184
+ if ( durableTaskConfig . Any ( )
180
185
&& ( t [ "type" ] ? . ToString ( ) . Equals ( "orchestrationTrigger" , StringComparison . OrdinalIgnoreCase ) == true
181
186
|| t [ "type" ] ? . ToString ( ) . Equals ( "activityTrigger" , StringComparison . OrdinalIgnoreCase ) == true ) )
182
187
{
183
- t [ "taskHubName" ] = durableTaskHubName ;
188
+ if ( durableTaskConfig . ContainsKey ( HubName ) )
189
+ {
190
+ t [ TaskHubName ] = durableTaskConfig [ HubName ] ;
191
+ }
192
+
193
+ if ( durableTaskConfig . ContainsKey ( Connection ) )
194
+ {
195
+ t [ Connection ] = durableTaskConfig [ Connection ] ;
196
+ }
184
197
}
185
198
return t ;
186
199
} ) ;
@@ -225,22 +238,48 @@ private IEnumerable<FunctionMetadata> GetFunctionsMetadata()
225
238
. ReadFunctionsMetadata ( FileUtility . EnumerateDirectories ( _config . RootScriptPath ) , _logger , new Dictionary < string , Collection < string > > ( ) , fileSystem : FileUtility . Instance ) ;
226
239
}
227
240
228
- private async Task < string > GetDurableTaskHubName ( )
241
+ private async Task < Dictionary < string , string > > ReadDurableTaskConfig ( )
229
242
{
230
243
string hostJsonPath = Path . Combine ( _config . RootScriptPath , ScriptConstants . HostMetadataFileName ) ;
244
+ var config = new Dictionary < string , string > ( ) ;
231
245
if ( FileUtility . FileExists ( hostJsonPath ) )
232
246
{
247
+ var hostJson = JObject . Parse ( await FileUtility . ReadAsync ( hostJsonPath ) ) ;
248
+ JToken durableTaskValue ;
249
+
250
+ // we will allow case insensitivity given it is likely user hand edited
251
+ // see https://github.com/Azure/azure-functions-durable-extension/issues/111
252
+ //
233
253
// We're looking for {VALUE}
234
254
// {
235
255
// "durableTask": {
236
- // "HubName": "{VALUE}"
256
+ // "hubName": "{VALUE}",
257
+ // "azureStorageConnectionStringName": "{VALUE}"
237
258
// }
238
259
// }
239
- var hostJson = JsonConvert . DeserializeObject < HostJsonModel > ( await FileUtility . ReadAsync ( hostJsonPath ) ) ;
240
- return hostJson ? . DurableTask ? . HubName ;
260
+ if ( hostJson . TryGetValue ( DurableTask , StringComparison . OrdinalIgnoreCase , out durableTaskValue ) && durableTaskValue != null )
261
+ {
262
+ try
263
+ {
264
+ var kvp = ( JObject ) durableTaskValue ;
265
+ if ( kvp . TryGetValue ( HubName , StringComparison . OrdinalIgnoreCase , out JToken nameValue ) && nameValue != null )
266
+ {
267
+ config . Add ( HubName , nameValue . ToString ( ) ) ;
268
+ }
269
+
270
+ if ( kvp . TryGetValue ( DurableTaskStorageConnectionName , StringComparison . OrdinalIgnoreCase , out nameValue ) && nameValue != null )
271
+ {
272
+ config . Add ( Connection , nameValue . ToString ( ) ) ;
273
+ }
274
+ }
275
+ catch ( Exception )
276
+ {
277
+ throw new InvalidDataException ( "Invalid host.json configuration for 'durableTask'." ) ;
278
+ }
279
+ }
241
280
}
242
281
243
- return null ;
282
+ return config ;
244
283
}
245
284
246
285
private void DeleteFunctionArtifacts ( FunctionMetadataResponse function )
@@ -252,15 +291,5 @@ private void DeleteFunctionArtifacts(FunctionMetadataResponse function)
252
291
FileUtility . DeleteFileSafe ( testDataPath ) ;
253
292
}
254
293
}
255
-
256
- private class HostJsonModel
257
- {
258
- public DurableTaskHostModel DurableTask { get ; set ; }
259
- }
260
-
261
- private class DurableTaskHostModel
262
- {
263
- public string HubName { get ; set ; }
264
- }
265
294
}
266
295
}
0 commit comments