Skip to content

Commit 136f0ef

Browse files
committed
Refactoring the FunctionDescriptorProvider hierarchy
1 parent 2827549 commit 136f0ef

File tree

13 files changed

+117
-171
lines changed

13 files changed

+117
-171
lines changed

src/WebJobs.Script.WebHost/WebHooks/WebHookReceiverManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public async Task<HttpResponseMessage> HandleRequestAsync(FunctionDescriptor fun
4949
HttpBindingMetadata httpFunctionMetadata = (HttpBindingMetadata)function.Metadata.InputBindings.FirstOrDefault(p => p.Type == BindingType.HttpTrigger);
5050
string webHookReceiver = httpFunctionMetadata.WebHookReceiver;
5151
IWebHookReceiver receiver = null;
52-
if (!string.IsNullOrEmpty(webHookReceiver) || !_receiverLookup.TryGetValue(webHookReceiver, out receiver))
52+
if (string.IsNullOrEmpty(webHookReceiver) || !_receiverLookup.TryGetValue(webHookReceiver, out receiver))
5353
{
5454
// If the function is a not a correctly configured WebHook return 500
5555
return new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError);

src/WebJobs.Script/Binding/BindingContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Microsoft.Azure.WebJobs.Script.Binding
55
{
6-
internal class BindingContext
6+
public class BindingContext
77
{
88
public IBinder Binder { get; set; }
99

src/WebJobs.Script/Binding/BlobBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Microsoft.Azure.WebJobs.Script.Binding
1010
{
11-
internal class BlobBinding : FunctionBinding
11+
public class BlobBinding : FunctionBinding
1212
{
1313
private readonly BindingTemplate _pathBindingTemplate;
1414

src/WebJobs.Script/Binding/FunctionBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace Microsoft.Azure.WebJobs.Script.Binding
1414
{
15-
internal abstract class FunctionBinding
15+
public abstract class FunctionBinding
1616
{
1717
private readonly ScriptHostConfiguration _config;
1818

src/WebJobs.Script/Binding/HttpBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace Microsoft.Azure.WebJobs.Script.Binding
1313
{
14-
internal class HttpBinding : FunctionBinding
14+
public class HttpBinding : FunctionBinding
1515
{
1616
internal const string HttpResponsePropertyKey = "MS_AzureFunctionsHttpResponse";
1717

src/WebJobs.Script/Binding/QueueBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Microsoft.Azure.WebJobs.Script.Binding
1010
{
11-
internal class QueueBinding : FunctionBinding
11+
public class QueueBinding : FunctionBinding
1212
{
1313
private readonly BindingTemplate _queueNameBindingTemplate;
1414

src/WebJobs.Script/Binding/ServiceBusBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Microsoft.Azure.WebJobs.Script.Binding
1010
{
11-
internal class ServiceBusBinding : FunctionBinding
11+
public class ServiceBusBinding : FunctionBinding
1212
{
1313
private readonly BindingTemplate _queueOrTopicNameBindingTemplate;
1414

src/WebJobs.Script/Binding/TableBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace Microsoft.Azure.WebJobs.Script.Binding
1414
{
15-
internal class TableBinding : FunctionBinding
15+
public class TableBinding : FunctionBinding
1616
{
1717
private readonly BindingTemplate _partitionKeyBindingTemplate;
1818
private readonly BindingTemplate _rowKeyBindingTemplate;

src/WebJobs.Script/Description/FunctionDescriptorProvider.cs

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,104 @@
44
using System;
55
using System.Collections.ObjectModel;
66
using System.Diagnostics;
7+
using System.IO;
8+
using System.Linq;
9+
using System.Net.Http;
710
using System.Reflection;
811
using System.Reflection.Emit;
9-
using Microsoft.Azure.WebJobs.Script.Description;
12+
using Microsoft.Azure.WebJobs.Host;
13+
using Microsoft.Azure.WebJobs.Script.Binding;
1014
using Microsoft.ServiceBus.Messaging;
1115

1216
namespace Microsoft.Azure.WebJobs.Script.Description
1317
{
1418
public abstract class FunctionDescriptorProvider
1519
{
16-
public abstract bool TryCreate(FunctionMetadata metadata, out FunctionDescriptor functionDescriptor);
20+
public FunctionDescriptorProvider(ScriptHost host, ScriptHostConfiguration config)
21+
{
22+
Host = host;
23+
Config = config;
24+
}
25+
26+
protected ScriptHost Host { get; private set; }
27+
28+
protected ScriptHostConfiguration Config { get; private set; }
29+
30+
public virtual bool TryCreate(FunctionMetadata functionMetadata, out FunctionDescriptor functionDescriptor)
31+
{
32+
functionDescriptor = null;
33+
34+
if (functionMetadata.IsDisabled)
35+
{
36+
return false;
37+
}
38+
39+
// parse the bindings
40+
Collection<FunctionBinding> inputBindings = FunctionBinding.GetBindings(Config, functionMetadata.InputBindings, FileAccess.Read);
41+
Collection<FunctionBinding> outputBindings = FunctionBinding.GetBindings(Config, functionMetadata.OutputBindings, FileAccess.Write);
42+
43+
BindingMetadata triggerMetadata = functionMetadata.InputBindings.FirstOrDefault(p => p.IsTrigger);
44+
BindingType triggerType = triggerMetadata.Type;
45+
string triggerParameterName = triggerMetadata.Name;
46+
bool triggerNameSpecified = true;
47+
if (string.IsNullOrEmpty(triggerParameterName))
48+
{
49+
// default the name to simply 'input'
50+
triggerMetadata.Name = triggerParameterName = "input";
51+
triggerNameSpecified = false;
52+
}
53+
54+
Collection<CustomAttributeBuilder> methodAttributes = new Collection<CustomAttributeBuilder>();
55+
ParameterDescriptor triggerParameter = null;
56+
bool omitInputParameter = false;
57+
switch (triggerType)
58+
{
59+
case BindingType.QueueTrigger:
60+
triggerParameter = ParseQueueTrigger((QueueBindingMetadata)triggerMetadata);
61+
break;
62+
case BindingType.BlobTrigger:
63+
triggerParameter = ParseBlobTrigger((BlobBindingMetadata)triggerMetadata);
64+
break;
65+
case BindingType.ServiceBusTrigger:
66+
triggerParameter = ParseServiceBusTrigger((ServiceBusBindingMetadata)triggerMetadata);
67+
break;
68+
case BindingType.TimerTrigger:
69+
omitInputParameter = true;
70+
triggerParameter = ParseTimerTrigger((TimerBindingMetadata)triggerMetadata, typeof(TimerInfo));
71+
break;
72+
case BindingType.HttpTrigger:
73+
if (!triggerNameSpecified)
74+
{
75+
triggerMetadata.Name = triggerParameterName = "req";
76+
}
77+
triggerParameter = ParseHttpTrigger((HttpBindingMetadata)triggerMetadata, methodAttributes, typeof(HttpRequestMessage));
78+
break;
79+
case BindingType.ManualTrigger:
80+
triggerParameter = ParseManualTrigger(triggerMetadata, methodAttributes);
81+
break;
82+
}
83+
84+
Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>();
85+
triggerParameter.IsTrigger = true;
86+
parameters.Add(triggerParameter);
87+
88+
// Add a TraceWriter for logging
89+
parameters.Add(new ParameterDescriptor("log", typeof(TraceWriter)));
90+
91+
// Add an IBinder to support the binding programming model
92+
parameters.Add(new ParameterDescriptor("binder", typeof(IBinder)));
93+
94+
// Add ExecutionContext to provide access to InvocationId, etc.
95+
parameters.Add(new ParameterDescriptor("context", typeof(ExecutionContext)));
96+
97+
string scriptFilePath = Path.Combine(Config.RootScriptPath, functionMetadata.Source);
98+
IFunctionInvoker invoker = CreateFunctionInvoker(scriptFilePath, triggerMetadata, functionMetadata, omitInputParameter, inputBindings, outputBindings);
99+
functionDescriptor = new FunctionDescriptor(functionMetadata.Name, invoker, functionMetadata, parameters, methodAttributes);
100+
101+
return true;
102+
}
103+
104+
protected abstract IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, bool omitInputParameter, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings);
17105

18106
protected ParameterDescriptor ParseQueueTrigger(QueueBindingMetadata trigger, Type triggerParameterType = null)
19107
{

src/WebJobs.Script/Description/NodeFunctionDescriptorProvider.cs

Lines changed: 8 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,105 +3,33 @@
33

44
using System.Collections.ObjectModel;
55
using System.IO;
6-
using System.Linq;
7-
using System.Net.Http;
8-
using System.Reflection.Emit;
9-
using Microsoft.Azure.WebJobs.Host;
106
using Microsoft.Azure.WebJobs.Script.Binding;
117

128
namespace Microsoft.Azure.WebJobs.Script.Description
139
{
1410
internal class NodeFunctionDescriptorProvider : FunctionDescriptorProvider
1511
{
16-
private ScriptHost _host;
17-
private readonly ScriptHostConfiguration _config;
18-
private readonly string _rootPath;
19-
2012
public NodeFunctionDescriptorProvider(ScriptHost host, ScriptHostConfiguration config)
13+
: base (host, config)
2114
{
22-
_host = host;
23-
_config = config;
24-
_rootPath = config.RootScriptPath;
2515
}
2616

27-
public override bool TryCreate(FunctionMetadata metadata, out FunctionDescriptor functionDescriptor)
17+
public override bool TryCreate(FunctionMetadata functionMetadata, out FunctionDescriptor functionDescriptor)
2818
{
2919
functionDescriptor = null;
3020

31-
// name might point to a single file, or a module
32-
string extension = Path.GetExtension(metadata.Source).ToLower();
21+
string extension = Path.GetExtension(functionMetadata.Source).ToLower();
3322
if (!(extension == ".js" || string.IsNullOrEmpty(extension)))
3423
{
3524
return false;
3625
}
3726

38-
if (metadata.IsDisabled)
39-
{
40-
return false;
41-
}
42-
43-
// parse the bindings
44-
Collection<FunctionBinding> inputBindings = FunctionBinding.GetBindings(_config, metadata.InputBindings, FileAccess.Read);
45-
Collection<FunctionBinding> outputBindings = FunctionBinding.GetBindings(_config, metadata.OutputBindings, FileAccess.Write);
46-
47-
BindingMetadata triggerMetadata = metadata.InputBindings.FirstOrDefault(p => p.IsTrigger);
48-
BindingType triggerType = triggerMetadata.Type;
49-
string triggerParameterName = triggerMetadata.Name;
50-
bool triggerNameSpecified = true;
51-
if (string.IsNullOrEmpty(triggerParameterName))
52-
{
53-
// default the name to simply 'input'
54-
triggerMetadata.Name = triggerParameterName = "input";
55-
triggerNameSpecified = false;
56-
}
57-
58-
Collection<CustomAttributeBuilder> methodAttributes = new Collection<CustomAttributeBuilder>();
59-
ParameterDescriptor triggerParameter = null;
60-
bool omitInputParameter = false;
61-
switch (triggerType)
62-
{
63-
case BindingType.QueueTrigger:
64-
triggerParameter = ParseQueueTrigger((QueueBindingMetadata)triggerMetadata);
65-
break;
66-
case BindingType.BlobTrigger:
67-
triggerParameter = ParseBlobTrigger((BlobBindingMetadata)triggerMetadata);
68-
break;
69-
case BindingType.ServiceBusTrigger:
70-
triggerParameter = ParseServiceBusTrigger((ServiceBusBindingMetadata)triggerMetadata);
71-
break;
72-
case BindingType.TimerTrigger:
73-
omitInputParameter = true;
74-
triggerParameter = ParseTimerTrigger((TimerBindingMetadata)triggerMetadata, typeof(TimerInfo));
75-
break;
76-
case BindingType.HttpTrigger:
77-
if (!triggerNameSpecified)
78-
{
79-
triggerMetadata.Name = triggerParameterName = "req";
80-
}
81-
triggerParameter = ParseHttpTrigger((HttpBindingMetadata)triggerMetadata, methodAttributes, typeof(HttpRequestMessage));
82-
break;
83-
case BindingType.ManualTrigger:
84-
triggerParameter = ParseManualTrigger(triggerMetadata, methodAttributes);
85-
break;
86-
}
87-
88-
Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>();
89-
triggerParameter.IsTrigger = true;
90-
parameters.Add(triggerParameter);
91-
92-
// Add a TraceWriter for logging
93-
parameters.Add(new ParameterDescriptor("log", typeof(TraceWriter)));
94-
95-
// Add an IBinder to support the binding programming model
96-
parameters.Add(new ParameterDescriptor("binder", typeof(IBinder)));
97-
98-
// Add ExecutionContext to provide access to InvocationId, etc.
99-
parameters.Add(new ParameterDescriptor("context", typeof(ExecutionContext)));
100-
101-
NodeFunctionInvoker invoker = new NodeFunctionInvoker(_host, triggerMetadata, omitInputParameter, metadata, inputBindings, outputBindings);
102-
functionDescriptor = new FunctionDescriptor(metadata.Name, invoker, metadata, parameters, methodAttributes);
27+
return base.TryCreate(functionMetadata, out functionDescriptor);
28+
}
10329

104-
return true;
30+
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, bool omitInputParameter, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings)
31+
{
32+
return new NodeFunctionInvoker(Host, triggerMetadata, functionMetadata, omitInputParameter, inputBindings, outputBindings);
10533
}
10634
}
10735
}

0 commit comments

Comments
 (0)