@@ -22,8 +22,9 @@ public static class FunctionMetadataExtensions
2222 /// <returns>Promise of a FunctionMetadataResponse</returns>
2323 public static async Task < FunctionMetadataResponse > ToFunctionMetadataResponse ( this FunctionMetadata functionMetadata , ScriptJobHostOptions hostOptions , string routePrefix , string baseUrl )
2424 {
25- var functionPath = Path . Combine ( hostOptions . RootScriptPath , functionMetadata . Name ) ;
26- var functionMetadataFilePath = Path . Combine ( functionPath , ScriptConstants . FunctionMetadataFileName ) ;
25+ string functionPath = GetFunctionPathOrNull ( hostOptions . RootScriptPath , functionMetadata . Name ) ;
26+ string functionMetadataFilePath = GetMetadataPathOrNull ( functionPath ) ;
27+
2728 if ( string . IsNullOrEmpty ( baseUrl ) )
2829 {
2930 baseUrl = "https://localhost/" ;
@@ -32,10 +33,8 @@ public static async Task<FunctionMetadataResponse> ToFunctionMetadataResponse(th
3233 var response = new FunctionMetadataResponse
3334 {
3435 Name = functionMetadata . Name ,
35- ConfigHref = VirtualFileSystem . FilePathToVfsUri ( functionMetadataFilePath , baseUrl , hostOptions ) ,
36- ScriptRootPathHref = VirtualFileSystem . FilePathToVfsUri ( functionPath , baseUrl , hostOptions , isDirectory : true ) ,
3736 Href = GetFunctionHref ( functionMetadata . Name , baseUrl ) ,
38- Config = await GetFunctionConfig ( functionMetadataFilePath ) ,
37+ Config = await GetFunctionConfig ( functionMetadata , functionMetadataFilePath ) ,
3938
4039 // Properties below this comment are not present in the kudu version.
4140 IsDirect = functionMetadata . IsDirect ( ) ,
@@ -45,6 +44,16 @@ public static async Task<FunctionMetadataResponse> ToFunctionMetadataResponse(th
4544 InvokeUrlTemplate = GetFunctionInvokeUrlTemplate ( baseUrl , functionMetadata , routePrefix )
4645 } ;
4746
47+ if ( ! string . IsNullOrEmpty ( functionPath ) )
48+ {
49+ response . ScriptRootPathHref = VirtualFileSystem . FilePathToVfsUri ( functionPath , baseUrl , hostOptions , isDirectory : true ) ;
50+ }
51+
52+ if ( ! string . IsNullOrEmpty ( functionMetadataFilePath ) )
53+ {
54+ response . ConfigHref = VirtualFileSystem . FilePathToVfsUri ( functionMetadataFilePath , baseUrl , hostOptions ) ;
55+ }
56+
4857 if ( ! string . IsNullOrEmpty ( hostOptions . TestDataPath ) )
4958 {
5059 var testDataFilePath = functionMetadata . GetTestDataFilePath ( hostOptions ) ;
@@ -69,29 +78,12 @@ public static async Task<FunctionMetadataResponse> ToFunctionMetadataResponse(th
6978 /// <param name="config">ScriptHostConfiguration to read RootScriptPath from.</param>
7079 /// <returns>JObject that represent the trigger for scale controller to consume</returns>
7180 public static async Task < JObject > ToFunctionTrigger ( this FunctionMetadata functionMetadata , ScriptJobHostOptions config )
72- {
73- // Codeless functions do not have a physical file and need to be converted differently.
74- if ( functionMetadata . IsCodeless ( ) )
75- {
76- return await GetCodelessFunctionTrigger ( functionMetadata ) ;
77- }
78-
79- return await GetRegularFunctionTrigger ( functionMetadata , config ) ;
80- }
81-
82- public static string GetTestDataFilePath ( this FunctionMetadata functionMetadata , ScriptJobHostOptions hostOptions ) =>
83- GetTestDataFilePath ( functionMetadata . Name , hostOptions ) ;
84-
85- public static string GetTestDataFilePath ( string functionName , ScriptJobHostOptions hostOptions ) =>
86- Path . Combine ( hostOptions . TestDataPath , $ "{ functionName } .dat") ;
87-
88- private static async Task < JObject > GetRegularFunctionTrigger ( FunctionMetadata functionMetadata , ScriptJobHostOptions config )
8981 {
9082 var functionPath = Path . Combine ( config . RootScriptPath , functionMetadata . Name ) ;
9183 var functionMetadataFilePath = Path . Combine ( functionPath , ScriptConstants . FunctionMetadataFileName ) ;
9284
9385 // Read function.json as a JObject
94- var functionConfig = await GetFunctionConfig ( functionMetadataFilePath ) ;
86+ var functionConfig = await GetFunctionConfig ( functionMetadata , functionMetadataFilePath ) ;
9587
9688 if ( functionConfig . TryGetValue ( "bindings" , out JToken value ) &&
9789 value is JArray )
@@ -112,35 +104,50 @@ private static async Task<JObject> GetRegularFunctionTrigger(FunctionMetadata fu
112104 return null ;
113105 }
114106
115- private static Task < JObject > GetCodelessFunctionTrigger ( FunctionMetadata functionMetadata )
107+ public static string GetTestDataFilePath ( this FunctionMetadata functionMetadata , ScriptJobHostOptions hostOptions ) =>
108+ GetTestDataFilePath ( functionMetadata . Name , hostOptions ) ;
109+
110+ public static string GetTestDataFilePath ( string functionName , ScriptJobHostOptions hostOptions ) =>
111+ Path . Combine ( hostOptions . TestDataPath , $ "{ functionName } .dat") ;
112+
113+ private static string GetFunctionPathOrNull ( string scriptRoot , string functionName )
116114 {
117- if ( functionMetadata . Bindings == null )
115+ var functionPath = Path . Combine ( scriptRoot , functionName ) ;
116+
117+ if ( FileUtility . DirectoryExists ( functionPath ) )
118118 {
119- return null ;
119+ return functionPath ;
120120 }
121121
122- foreach ( BindingMetadata binding in functionMetadata . Bindings )
122+ return null ;
123+ }
124+
125+ private static string GetMetadataPathOrNull ( string functionPath )
126+ {
127+ if ( ! string . IsNullOrEmpty ( functionPath ) )
123128 {
124- JObject rawBinding = binding . Raw ;
125- var type = ( string ) rawBinding [ "type" ] ;
126- if ( type != null && type . EndsWith ( "Trigger" , StringComparison . OrdinalIgnoreCase ) )
129+ var metadataPath = Path . Combine ( functionPath , ScriptConstants . FunctionMetadataFileName ) ;
130+
131+ if ( FileUtility . FileExists ( metadataPath ) )
127132 {
128- JObject newBinding = ( JObject ) rawBinding . DeepClone ( ) ;
129- newBinding . Add ( "functionName" , functionMetadata . Name ) ;
130- return Task . FromResult ( newBinding ) ;
133+ return metadataPath ;
131134 }
132135 }
133136
134137 return null ;
135138 }
136139
137- private static async Task < JObject > GetFunctionConfig ( string path )
140+ private static async Task < JObject > GetFunctionConfig ( FunctionMetadata metadata , string path )
138141 {
139142 try
140143 {
141- if ( FileUtility . FileExists ( path ) )
144+ if ( ! string . IsNullOrEmpty ( path ) && FileUtility . FileExists ( path ) )
145+ {
146+ return await GetFunctionConfigFromFile ( path ) ;
147+ }
148+ else
142149 {
143- return JObject . Parse ( await FileUtility . ReadAsync ( path ) ) ;
150+ return GetFunctionConfigFromMetadata ( metadata ) ;
144151 }
145152 }
146153 catch
@@ -154,6 +161,26 @@ private static async Task<JObject> GetFunctionConfig(string path)
154161 return new JObject ( ) ;
155162 }
156163
164+ private static async Task < JObject > GetFunctionConfigFromFile ( string path )
165+ {
166+ return JObject . Parse ( await FileUtility . ReadAsync ( path ) ) ;
167+ }
168+
169+ private static JObject GetFunctionConfigFromMetadata ( FunctionMetadata metadata )
170+ {
171+ var config = new
172+ {
173+ name = metadata . Name ,
174+ entryPoint = metadata . EntryPoint ,
175+ scriptFile = metadata . ScriptFile ,
176+ language = metadata . Language ,
177+ functionDirectory = metadata . FunctionDirectory ,
178+ bindings = metadata . Bindings . Select ( m => m . Raw ) . ToList ( )
179+ } ;
180+
181+ return JObject . FromObject ( config ) ;
182+ }
183+
157184 private static async Task < string > GetTestData ( string testDataPath , ScriptJobHostOptions config )
158185 {
159186 if ( ! File . Exists ( testDataPath ) )
0 commit comments