Skip to content

Commit 54aa088

Browse files
committed
Apply FunctionDescriptor to route DataTokens
1 parent a7c9730 commit 54aa088

17 files changed

+159
-93
lines changed

src/WebJobs.Script.NuGet/WebJobs.Script.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<dependency id="Microsoft.Azure.WebJobs.Extensions.ApiHub" version="1.0.0-beta6-10554" />
2525
<dependency id="Microsoft.Azure.WebJobs.Extensions.BotFramework" version="1.0.15-beta" />
2626
<dependency id="Microsoft.Azure.WebJobs.Extensions.DocumentDB" version="1.1.0-beta4-10554" />
27-
<dependency id="Microsoft.Azure.WebJobs.Extensions.Http" version="1.0.0-beta4-10554" />
27+
<dependency id="Microsoft.Azure.WebJobs.Extensions.Http" version="1.0.0-beta4-10574" />
2828
<dependency id="Microsoft.Azure.WebJobs.Extensions.MobileApps" version="1.1.0-beta4-10554" />
2929
<dependency id="Microsoft.Azure.WebJobs.Extensions.NotificationHubs" version="1.1.0-beta4-10554" />
3030
<dependency id="Microsoft.Azure.WebJobs.Extensions.SendGrid" version="2.1.0-beta4-10554" />

src/WebJobs.Script.WebHost/Controllers/SwaggerController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public IHttpActionResult GetGeneratedSwaggerDocument()
3535
{
3636
_traceWriter.Verbose(Resources.SwaggerGenerateDocument);
3737
_logger?.LogDebug(Resources.SwaggerGenerateDocument);
38-
var swaggerDocument = _swaggerDocumentManager.GenerateSwaggerDocument(_scriptHostManager.HttpFunctions);
38+
var swaggerDocument = _swaggerDocumentManager.GenerateSwaggerDocument(_scriptHostManager.Routes);
3939
return Ok(swaggerDocument);
4040
}
4141

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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.Linq;
5+
using System.Net.Http;
6+
using System.Web.Http;
7+
using System.Web.Http.Routing;
8+
using Microsoft.Azure.WebJobs.Script.Description;
9+
10+
namespace Microsoft.Azure.WebJobs.Script.WebHost.Extensions
11+
{
12+
public static class HttpRouteCollectionExtensions
13+
{
14+
public static IHttpRouteData GetRouteData(this HttpRouteCollection routes, HttpRequestMessage request, bool proxyRoutesFirst = true)
15+
{
16+
if (!proxyRoutesFirst)
17+
{
18+
// order proxy routes last
19+
var orderedRoutes = routes.OrderBy(p => ((FunctionDescriptor)p.DataTokens[ScriptConstants.AzureFunctionsHttpFunctionKey]).Metadata.IsProxy ? 1 : 0);
20+
return orderedRoutes.Select(p => p.GetRouteData(routes.VirtualPathRoot, request)).FirstOrDefault(p => p != null);
21+
}
22+
else
23+
{
24+
// do the default query
25+
return routes.GetRouteData(request);
26+
}
27+
}
28+
}
29+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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.Collections.Generic;
5+
using System.Linq;
6+
using System.Net.Http;
7+
using System.Web.Http;
8+
using System.Web.Http.Routing;
9+
using Microsoft.Azure.WebJobs.Script;
10+
using Microsoft.Azure.WebJobs.Script.Description;
11+
12+
namespace Microsoft.Azure.WebJobs.Extensions.Http
13+
{
14+
public static class HttpRouteFactoryExtensions
15+
{
16+
public static bool TryAddRoute(this HttpRouteFactory httpRouteFactory, HttpRouteCollection httpRoutes, FunctionDescriptor function)
17+
{
18+
var httpTrigger = function.GetTriggerAttributeOrNull<HttpTriggerAttribute>();
19+
if (httpTrigger != null)
20+
{
21+
IHttpRoute httpRoute = null;
22+
IEnumerable<HttpMethod> httpMethods = null;
23+
if (httpTrigger.Methods != null)
24+
{
25+
httpMethods = httpTrigger.Methods.Select(p => new HttpMethod(p)).ToArray();
26+
}
27+
var dataTokens = new Dictionary<string, object>
28+
{
29+
{ ScriptConstants.AzureFunctionsHttpFunctionKey, function }
30+
};
31+
return httpRouteFactory.TryAddRoute(function.Metadata.Name, httpTrigger.Route, httpMethods, dataTokens, httpRoutes, out httpRoute);
32+
}
33+
34+
return false;
35+
}
36+
}
37+
}

src/WebJobs.Script.WebHost/ProxyFunctionExecutor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ public async Task ExecuteFuncAsync(string funcName, Dictionary<string, object> a
6363
// 1. If the request maps to a local http trigger function name then that function will be picked.
6464
// 2. Else if the request maps to a custom route of a local http trigger function then that function will be picked
6565
// 3. Otherwise the request will be given to asp.net to pick the appropriate route.
66-
foreach (var func in _scriptHostManager.HttpFunctions.Values)
66+
foreach (var route in _scriptHostManager.Routes)
6767
{
68+
var func = (FunctionDescriptor)route.DataTokens[ScriptConstants.AzureFunctionsHttpFunctionKey];
6869
if (!func.Metadata.IsProxy)
6970
{
7071
if (path.Equals(func.Metadata.Name, StringComparison.OrdinalIgnoreCase))

src/WebJobs.Script.WebHost/Swagger/ISwaggerDocumentManager.cs

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

44
using System.Collections.Generic;
55
using System.Threading.Tasks;
6+
using System.Web.Http;
67
using System.Web.Http.Routing;
78
using Microsoft.Azure.WebJobs.Script.Description;
89
using Newtonsoft.Json.Linq;
@@ -31,10 +32,10 @@ public interface ISwaggerDocumentManager
3132
Task<JObject> AddOrUpdateSwaggerDocumentAsync(JObject swaggerDocumentJson);
3233

3334
/// <summary>
34-
/// Generates a Swagger document as a JSON object using the information present in <paramref name="httpFunctions"/>
35+
/// Generates a Swagger document as a JSON object using the information present in the route collection.
3536
/// </summary>
36-
/// <param name="httpFunctions">Dictionary with the route information and the functions metadata</param>
37-
/// <returns></returns>
38-
JObject GenerateSwaggerDocument(IReadOnlyDictionary<IHttpRoute, FunctionDescriptor> httpFunctions);
37+
/// <param name="routes">The mapped http routes</param>
38+
/// <returns>The Swagger document</returns>
39+
JObject GenerateSwaggerDocument(HttpRouteCollection routes);
3940
}
4041
}

src/WebJobs.Script.WebHost/Swagger/SwaggerDocumentManager.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Linq;
88
using System.Net.Http;
99
using System.Threading.Tasks;
10+
using System.Web.Http;
1011
using System.Web.Http.Routing;
1112
using Microsoft.Azure.WebJobs.Extensions.Http;
1213
using Microsoft.Azure.WebJobs.Script.Binding;
@@ -32,36 +33,37 @@ public SwaggerDocumentManager(ScriptHostConfiguration hostConfig)
3233

3334
public async Task<JObject> GetSwaggerDocumentAsync() => await ReadSwaggerAsync();
3435

35-
public JObject GenerateSwaggerDocument(IReadOnlyDictionary<IHttpRoute, FunctionDescriptor> httpFunctions)
36+
public JObject GenerateSwaggerDocument(HttpRouteCollection routes)
3637
{
3738
var swaggerDocument = new SwaggerDocument();
3839
string hostname = ScriptSettingsManager.Instance.GetSetting(EnvironmentSettingNames.AzureWebsiteHostName);
3940
swaggerDocument.SwaggerInfo.FunctionAppName = hostname;
4041
swaggerDocument.Host = hostname;
41-
swaggerDocument.ApiEndpoints = GetEndpointsData(httpFunctions);
42+
swaggerDocument.ApiEndpoints = GetEndpointsData(routes);
4243
return JObject.FromObject(swaggerDocument);
4344
}
4445

45-
private static Dictionary<string, Dictionary<string, HttpOperationInfo>> GetEndpointsData(IReadOnlyDictionary<IHttpRoute, FunctionDescriptor> httpFunctions)
46+
private static Dictionary<string, Dictionary<string, HttpOperationInfo>> GetEndpointsData(HttpRouteCollection routes)
4647
{
4748
var apiEndpoints = new Dictionary<string, Dictionary<string, HttpOperationInfo>>();
48-
foreach (var httpRoute in httpFunctions.Keys)
49+
foreach (var route in routes)
4950
{
50-
if (httpFunctions[httpRoute].Metadata.IsDisabled == true)
51+
var functionDescriptor = (FunctionDescriptor)route.DataTokens[ScriptConstants.AzureFunctionsHttpFunctionKey];
52+
if (functionDescriptor.Metadata.IsDisabled)
5153
{
5254
continue;
5355
}
5456

55-
string endpoint = $"/{httpRoute.RouteTemplate}";
57+
string endpoint = $"/{route.RouteTemplate}";
5658
Dictionary<string, HttpOperationInfo> endpointsOperationData;
5759
if (!apiEndpoints.TryGetValue(endpoint, out endpointsOperationData))
5860
{
5961
endpointsOperationData = new Dictionary<string, HttpOperationInfo>();
6062
apiEndpoints.Add(endpoint, endpointsOperationData);
6163
}
6264

63-
string[] httpOperations = GetHttpOperations(httpRoute);
64-
ICollection<HttpOperationParameterInfo> inputParameters = GetInputParameters(httpRoute);
65+
string[] httpOperations = GetHttpOperations(route);
66+
ICollection<HttpOperationParameterInfo> inputParameters = GetInputParameters(route);
6567
foreach (var httpOperation in httpOperations)
6668
{
6769
// Trace is not recogized as an HttpMethod by swagger specification

src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@
202202
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.2.1.0-beta4-11100\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
203203
</Reference>
204204
<Reference Include="Microsoft.Azure.WebJobs.Extensions, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
205-
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.2.1.0-beta4-10554\lib\net45\Microsoft.Azure.WebJobs.Extensions.dll</HintPath>
205+
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.2.1.0-beta4-10574\lib\net45\Microsoft.Azure.WebJobs.Extensions.dll</HintPath>
206206
</Reference>
207207
<Reference Include="Microsoft.Azure.WebJobs.Extensions.ApiHub, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
208208
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.ApiHub.1.0.0-beta6-10554\lib\net45\Microsoft.Azure.WebJobs.Extensions.ApiHub.dll</HintPath>
@@ -217,7 +217,7 @@
217217
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.EventGrid.1.0.0-beta2-10009\lib\net46\Microsoft.Azure.WebJobs.Extensions.EventGrid.dll</HintPath>
218218
</Reference>
219219
<Reference Include="Microsoft.Azure.WebJobs.Extensions.Http, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
220-
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.Http.1.0.0-beta4-10554\lib\net45\Microsoft.Azure.WebJobs.Extensions.Http.dll</HintPath>
220+
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.Http.1.0.0-beta4-10574\lib\net45\Microsoft.Azure.WebJobs.Extensions.Http.dll</HintPath>
221221
</Reference>
222222
<Reference Include="Microsoft.Azure.WebJobs.Extensions.MobileApps, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
223223
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.MobileApps.1.1.0-beta4-10554\lib\net45\Microsoft.Azure.WebJobs.Extensions.MobileApps.dll</HintPath>
@@ -437,6 +437,8 @@
437437
<Compile Include="App_Start\WebHostResolver.cs" />
438438
<Compile Include="App_Start\WebHostSettings.cs" />
439439
<Compile Include="Diagnostics\Sanitizer.cs" />
440+
<Compile Include="Extensions\HttpRouteCollectionExtensions.cs" />
441+
<Compile Include="Extensions\HttpRouteFactoryExtensions.cs" />
440442
<Compile Include="Filters\RequiresRunningHostAttribute.cs" />
441443
<Compile Include="StandbyManager.cs" />
442444
<Compile Include="Controllers\AdminController.cs" />

src/WebJobs.Script.WebHost/WebScriptHostManager.cs

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public class WebScriptHostManager : ScriptHostManager
4646
private readonly WebJobsSdkExtensionHookProvider _bindingWebHookProvider;
4747

4848
private bool _hostStarted = false;
49-
private IDictionary<IHttpRoute, FunctionDescriptor> _httpFunctions;
5049
private HttpRouteCollection _httpRoutes;
5150
private HttpRequestManager _httpRequestManager;
5251

@@ -147,11 +146,11 @@ public static bool InStandbyMode
147146
}
148147
}
149148

150-
public IReadOnlyDictionary<IHttpRoute, FunctionDescriptor> HttpFunctions
149+
public HttpRouteCollection Routes
151150
{
152151
get
153152
{
154-
return _httpFunctions as IReadOnlyDictionary<IHttpRoute, FunctionDescriptor>;
153+
return _httpRoutes;
155154
}
156155
}
157156

@@ -283,7 +282,7 @@ public FunctionDescriptor GetHttpFunctionOrNull(HttpRequestMessage request)
283282
throw new ArgumentNullException(nameof(request));
284283
}
285284

286-
if (_httpFunctions == null || _httpFunctions.Count == 0)
285+
if (_httpRoutes == null || _httpRoutes.Count == 0)
287286
{
288287
return null;
289288
}
@@ -292,7 +291,7 @@ public FunctionDescriptor GetHttpFunctionOrNull(HttpRequestMessage request)
292291
var routeData = _httpRoutes.GetRouteData(request);
293292
if (routeData != null)
294293
{
295-
_httpFunctions.TryGetValue(routeData.Route, out function);
294+
function = (FunctionDescriptor)routeData.Route.DataTokens[ScriptConstants.AzureFunctionsHttpFunctionKey];
296295
AddRouteDataToRequest(routeData, request);
297296
}
298297

@@ -390,30 +389,16 @@ private void InitializeHttpFunctions(IEnumerable<FunctionDescriptor> functions,
390389
// Proxies do not honor the route prefix defined in host.json
391390
var proxyHttpRouteFactory = new HttpRouteFactory(string.Empty);
392391

393-
_httpFunctions = new Dictionary<IHttpRoute, FunctionDescriptor>();
394392
_httpRoutes = new HttpRouteCollection();
395393

396394
// Proxy routes will take precedence over http trigger functions and http trigger
397395
// routes so they will be added first to the list of http routes.
398-
var orderdFunctions = functions.OrderBy(f => f.Metadata.IsProxy ? 0 : 1);
396+
var orderedFunctions = functions.OrderBy(f => f.Metadata.IsProxy ? 0 : 1);
399397

400-
foreach (var function in orderdFunctions)
398+
foreach (var function in orderedFunctions)
401399
{
402-
var httpTrigger = function.GetTriggerAttributeOrNull<HttpTriggerAttribute>();
403-
if (httpTrigger != null)
404-
{
405-
IHttpRoute httpRoute = null;
406-
IEnumerable<HttpMethod> httpMethods = null;
407-
if (httpTrigger.Methods != null)
408-
{
409-
httpMethods = httpTrigger.Methods.Select(p => new HttpMethod(p)).ToArray();
410-
}
411-
var httpRouteFactory = function.Metadata.IsProxy ? proxyHttpRouteFactory : functionHttpRouteFactory;
412-
if (httpRouteFactory.TryAddRoute(function.Metadata.Name, httpTrigger.Route, httpMethods, _httpRoutes, out httpRoute))
413-
{
414-
_httpFunctions.Add(httpRoute, function);
415-
}
416-
}
400+
var httpRouteFactory = function.Metadata.IsProxy ? proxyHttpRouteFactory : functionHttpRouteFactory;
401+
httpRouteFactory.TryAddRoute(_httpRoutes, function);
417402
}
418403
}
419404

src/WebJobs.Script.WebHost/packages.config

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@
4747
<package id="Microsoft.Azure.ServiceBus.EventProcessorHost" version="2.2.10" targetFramework="net46" />
4848
<package id="Microsoft.Azure.WebJobs" version="2.1.0-beta4-11100" targetFramework="net461" />
4949
<package id="Microsoft.Azure.WebJobs.Core" version="2.1.0-beta4-11100" targetFramework="net461" />
50-
<package id="Microsoft.Azure.WebJobs.Extensions" version="2.1.0-beta4-10554" targetFramework="net46" />
50+
<package id="Microsoft.Azure.WebJobs.Extensions" version="2.1.0-beta4-10574" targetFramework="net461" />
5151
<package id="Microsoft.Azure.WebJobs.Extensions.ApiHub" version="1.0.0-beta6-10554" targetFramework="net46" />
5252
<package id="Microsoft.Azure.WebJobs.Extensions.BotFramework" version="1.0.15-beta" targetFramework="net46" />
5353
<package id="Microsoft.Azure.WebJobs.Extensions.DocumentDB" version="1.1.0-beta4-10554" targetFramework="net46" />
5454
<package id="Microsoft.Azure.WebJobs.Extensions.EventGrid" version="1.0.0-beta2-10009" targetFramework="net46" />
55-
<package id="Microsoft.Azure.WebJobs.Extensions.Http" version="1.0.0-beta4-10554" targetFramework="net46" />
55+
<package id="Microsoft.Azure.WebJobs.Extensions.Http" version="1.0.0-beta4-10574" targetFramework="net461" />
5656
<package id="Microsoft.Azure.WebJobs.Extensions.MobileApps" version="1.1.0-beta4-10554" targetFramework="net46" />
5757
<package id="Microsoft.Azure.WebJobs.Extensions.NotificationHubs" version="1.1.0-beta4-10554" targetFramework="net46" />
5858
<package id="Microsoft.Azure.WebJobs.Extensions.SendGrid" version="2.1.0-beta4-10554" targetFramework="net46" />

0 commit comments

Comments
 (0)