public void GenerateQueueTriggerFunction_WithInvalidInputName_Fails() { string inputBindingName = "input"; string expectedError = "Input binding name 'input' is not allowed."; BindingMetadata trigger = new BindingMetadata { Type = "QueueTrigger", Name = inputBindingName }; trigger.Raw = new JObject { { "Type", "QueueTrigger" }, { "Name", inputBindingName }, { "Direction", "in" }, { "QueueName", "test" } }; using (var scriptHostInfo = GetScriptHostInfo()) { Exception ex = Assert.Throws<InvalidOperationException>(() => GenerateMethod(trigger, scriptHostInfo)); Assert.Equal("Sequence contains no elements", ex.Message); var functionError = scriptHostInfo.Host.FunctionErrors[FunctionName]; Assert.True(functionError.Contains(expectedError)); } }
protected internal override void ValidateBinding(BindingMetadata bindingMetadata) { base.ValidateBinding(bindingMetadata); if (string.Equals(bindingMetadata.Name, "input", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("Input binding name 'input' is not allowed."); } }
internal NodeFunctionInvoker(ScriptHost host, BindingMetadata trigger, FunctionMetadata functionMetadata, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) : base(host, functionMetadata) { _trigger = trigger; string scriptFilePath = functionMetadata.Source.Replace('\\', '/'); _script = string.Format(CultureInfo.InvariantCulture, _functionTemplate, scriptFilePath); _inputBindings = inputBindings; _outputBindings = outputBindings; _metrics = host.ScriptConfig.HostConfig.GetService<IMetricsLogger>(); InitializeFileWatcherIfEnabled(); }
public void GenerateManualTriggerFunction() { BindingMetadata trigger = new BindingMetadata { Type = BindingType.ManualTrigger }; MethodInfo method = GenerateMethod(trigger); VerifyCommonProperties(method); // verify trigger parameter ParameterInfo parameter = method.GetParameters()[0]; Assert.Equal("input", parameter.Name); Assert.Equal(typeof(string), parameter.ParameterType); NoAutomaticTriggerAttribute attribute = method.GetCustomAttribute<NoAutomaticTriggerAttribute>(); Assert.NotNull(attribute); }
internal ScriptFunctionInvoker(string scriptFilePath, ScriptHostConfiguration config, BindingMetadata trigger, FunctionMetadata functionMetadata, bool omitInputParameter, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { _scriptFilePath = scriptFilePath; _config = config; _scriptType = Path.GetExtension(_scriptFilePath).ToLower().TrimStart('.'); _inputBindings = inputBindings; _outputBindings = outputBindings; _functionName = functionMetadata.Name; _omitInputParameter = omitInputParameter; _trigger = trigger; if (config.FileLoggingEnabled) { string logFilePath = Path.Combine(_config.RootLogPath, "Function", _functionName); _fileTraceWriter = new FileTraceWriter(logFilePath, TraceLevel.Verbose); } else { _fileTraceWriter = NullTraceWriter.Instance; } }
protected virtual Collection<ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata); parameters.Add(triggerParameter); // Add a TraceWriter for logging parameters.Add(new ParameterDescriptor(ScriptConstants.SystemLogParameterName, typeof(TraceWriter))); // Add an IBinder to support the binding programming model parameters.Add(new ParameterDescriptor(ScriptConstants.SystemBinderParameterName, typeof(IBinder))); // Add ExecutionContext to provide access to InvocationId, etc. parameters.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext))); return parameters; }
protected virtual ParameterDescriptor CreateTriggerParameter(BindingMetadata triggerMetadata, Type parameterType = null) { ParameterDescriptor triggerParameter = null; string type = triggerMetadata.Type.ToLowerInvariant(); switch (type) { case "httptrigger": triggerParameter = ParseHttpTrigger((HttpTriggerBindingMetadata)triggerMetadata, parameterType ?? typeof(HttpRequestMessage)); break; case "manualtrigger": triggerParameter = ParseManualTrigger(triggerMetadata, parameterType ?? typeof(string)); break; default: TryParseTriggerParameter(triggerMetadata.Raw, out triggerParameter, parameterType); break; } triggerParameter.IsTrigger = true; return(triggerParameter); }
internal NodeFunctionInvoker(ScriptHost host, BindingMetadata trigger, FunctionMetadata metadata, bool omitInputParameter, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { _host = host; _trigger = trigger; _triggerParameterName = trigger.Name; _omitInputParameter = omitInputParameter; string scriptFilePath = metadata.Source.Replace('\\', '/'); _script = string.Format(FunctionTemplate, scriptFilePath); _inputBindings = inputBindings; _outputBindings = outputBindings; _functionMetadata = metadata; if (host.ScriptConfig.FileWatchingEnabled) { string functionDirectory = Path.GetDirectoryName(scriptFilePath); _fileWatcher = new FileSystemWatcher(functionDirectory, "*.*") { IncludeSubdirectories = true, EnableRaisingEvents = true }; _fileWatcher.Changed += OnScriptFileChanged; _fileWatcher.Created += OnScriptFileChanged; _fileWatcher.Deleted += OnScriptFileChanged; _fileWatcher.Renamed += OnScriptFileChanged; } if (_host.ScriptConfig.FileLoggingEnabled) { string logFilePath = Path.Combine(_host.ScriptConfig.RootLogPath, "Function", _functionMetadata.Name); _fileTraceWriter = new FileTraceWriter(logFilePath, TraceLevel.Verbose); } else { _fileTraceWriter = NullTraceWriter.Instance; } }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, bool omitInputParameter, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { return(new NodeFunctionInvoker(Host, triggerMetadata, functionMetadata, omitInputParameter, inputBindings, outputBindings)); }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { return(new DotNetFunctionInvoker(Host, functionMetadata, inputBindings, outputBindings, new FunctionEntryPointResolver(functionMetadata.EntryPoint), _assemblyLoader, _compilationServiceFactory)); }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { return new CSharpFunctionInvoker(Host, functionMetadata, inputBindings, outputBindings, new FunctionEntryPointResolver(), _assemblyLoader); }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { return(new WorkerLanguageInvoker(Host, triggerMetadata, functionMetadata, _loggerFactory, inputBindings, outputBindings, _dispatcher)); }
protected static void ApplyMethodLevelAttributes(FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes) { if (functionMetadata.IsDisabled || (triggerMetadata.Type == BindingType.HttpTrigger || triggerMetadata.Type == BindingType.ManualTrigger)) { // the function can be run manually, but there will be no automatic // triggering ConstructorInfo ctorInfo = typeof(NoAutomaticTriggerAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(ctorInfo, new object[0]); methodAttributes.Add(attributeBuilder); } }
protected virtual Collection<ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } ParameterDescriptor triggerParameter = null; switch (triggerMetadata.Type) { case BindingType.QueueTrigger: triggerParameter = ParseQueueTrigger((QueueBindingMetadata)triggerMetadata); break; case BindingType.EventHubTrigger: triggerParameter = ParseEventHubTrigger((EventHubBindingMetadata)triggerMetadata); break; case BindingType.BlobTrigger: triggerParameter = ParseBlobTrigger((BlobBindingMetadata)triggerMetadata, typeof(Stream)); break; case BindingType.ServiceBusTrigger: triggerParameter = ParseServiceBusTrigger((ServiceBusBindingMetadata)triggerMetadata); break; case BindingType.TimerTrigger: triggerParameter = ParseTimerTrigger((TimerBindingMetadata)triggerMetadata, typeof(TimerInfo)); break; case BindingType.HttpTrigger: triggerParameter = ParseHttpTrigger((HttpTriggerBindingMetadata)triggerMetadata, typeof(HttpRequestMessage)); break; case BindingType.ManualTrigger: triggerParameter = ParseManualTrigger(triggerMetadata); break; case BindingType.ApiHubTrigger: triggerParameter = ParseApiHubTrigger((ApiHubBindingMetadata)triggerMetadata, typeof(Stream)); break; } ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); triggerParameter.IsTrigger = true; parameters.Add(triggerParameter); // Add a TraceWriter for logging parameters.Add(new ParameterDescriptor("log", typeof(TraceWriter))); // Add an IBinder to support the binding programming model parameters.Add(new ParameterDescriptor("binder", typeof(IBinder))); // Add ExecutionContext to provide access to InvocationId, etc. parameters.Add(new ParameterDescriptor("context", typeof(ExecutionContext))); return parameters; }
protected abstract IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings);
protected virtual ParameterDescriptor CreateTriggerParameter(BindingMetadata triggerMetadata, Type parameterType = null) { if (TryParseTriggerParameter(triggerMetadata.Raw, out ParameterDescriptor triggerParameter, parameterType)) { triggerParameter.IsTrigger = true; }
protected override Collection<ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } var dotNetInvoker = functionInvoker as DotNetFunctionInvoker; if (dotNetInvoker == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(DotNetFunctionInvoker).Name, functionInvoker.GetType().Name)); } try { ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); MethodInfo functionTarget = dotNetInvoker.GetFunctionTargetAsync().Result; ParameterInfo[] parameters = functionTarget.GetParameters(); Collection<ParameterDescriptor> descriptors = new Collection<ParameterDescriptor>(); IEnumerable<FunctionBinding> bindings = inputBindings.Union(outputBindings); ParameterDescriptor descriptor = null; foreach (var parameter in parameters) { // Is it the trigger parameter? if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0) { ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata, parameter.ParameterType); descriptors.Add(triggerParameter); } else { Type parameterType = parameter.ParameterType; bool parameterIsByRef = parameterType.IsByRef; if (parameterIsByRef) { parameterType = parameterType.GetElementType(); } descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType); var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0); if (binding != null) { Collection<CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(parameter.ParameterType); if (customAttributes != null) { foreach (var customAttribute in customAttributes) { descriptor.CustomAttributes.Add(customAttribute); } } } // In the C# programming model, IsOut is set for out parameters // In the F# programming model, neither IsOut nor IsIn are set for byref parameters (which are used as out parameters). // Justification for this cariation of the programming model is that declaring 'out' parameters is (deliberately) // awkward in F#, they require opening System.Runtime.InteropServices and adding the [<Out>] attribute, and using // a byref parameter. In contrast declaring a byref parameter alone (neither labelled In nor Out) is simple enough. if (parameter.IsOut || (functionMetadata.ScriptType == ScriptType.FSharp && parameterIsByRef && !parameter.IsIn)) { descriptor.Attributes |= ParameterAttributes.Out; } descriptors.Add(descriptor); } } // Add any additional required System parameters (if they haven't already been defined by the user) if (!descriptors.Any(p => p.Type == typeof(ExecutionContext))) { // Add ExecutionContext to provide access to InvocationId, etc. descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext))); } // If we have an HTTP trigger binding but no parameter binds to the raw HttpRequestMessage, // add it as a system parameter so it is accessible later in the pipeline. if (string.Compare(triggerMetadata.Type, "httptrigger", StringComparison.OrdinalIgnoreCase) == 0 && !descriptors.Any(p => p.Type == typeof(HttpRequestMessage))) { descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemTriggerParameterName, typeof(HttpRequestMessage))); } if (TryCreateReturnValueParameterDescriptor(functionTarget.ReturnType, bindings, out descriptor)) { // If a return value binding has been specified, set up an output // binding to map it to. By convention, this is set up as the last // parameter. descriptors.Add(descriptor); } return descriptors; } catch (AggregateException exc) { if (!(exc.InnerException is CompilationErrorException)) { throw; } } catch (CompilationErrorException) { } // We were unable to compile the function to get its signature, // setup the descriptor with the default parameters methodAttributes.Clear(); return base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings); }
protected internal virtual void ValidateBinding(BindingMetadata bindingMetadata) { if (bindingMetadata.Name == null || !BindingNameValidationRegex.IsMatch(bindingMetadata.Name)) { throw new ArgumentException($"The binding name {bindingMetadata.Name} is invalid. Please assign a valid name to the binding."); } if (bindingMetadata.IsReturn && bindingMetadata.Direction != BindingDirection.Out) { throw new ArgumentException($"{ScriptConstants.SystemReturnParameterBindingName} bindings must specify a direction of 'out'."); } }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { return new DotNetFunctionInvoker(Host, functionMetadata, inputBindings, outputBindings, new FunctionEntryPointResolver(functionMetadata.EntryPoint), _assemblyLoader, _compilationServiceFactory); }
private static MethodInfo GenerateMethod(BindingMetadata trigger) { string rootPath = Path.Combine(Environment.CurrentDirectory, @"TestScripts\Node"); FunctionMetadata metadata = new FunctionMetadata(); metadata.Name = "Test"; metadata.ScriptFile = Path.Combine(rootPath, @"Common\test.js"); metadata.Bindings.Add(trigger); List<FunctionMetadata> functions = new List<FunctionMetadata>(); functions.Add(metadata); ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration() { RootScriptPath = rootPath }; Collection<FunctionDescriptor> functionDescriptors = null; using (ScriptHost host = ScriptHost.Create(SettingsManager, scriptConfig)) { FunctionDescriptorProvider[] descriptorProviders = new FunctionDescriptorProvider[] { new NodeFunctionDescriptorProvider(host, scriptConfig) }; functionDescriptors = host.ReadFunctions(functions, descriptorProviders); } Type t = FunctionGenerator.Generate("TestScriptHost", "Host.Functions", null, functionDescriptors); MethodInfo method = t.GetMethods(BindingFlags.Public | BindingFlags.Static).First(); return method; }
private static MethodInfo GenerateMethod(BindingMetadata trigger, ScriptHostInfo scriptHostInfo) { FunctionMetadata metadata = new FunctionMetadata(); metadata.Name = FunctionName; metadata.ScriptFile = Path.Combine(scriptHostInfo.RootPath, @"Common\test.ps1"); metadata.Bindings.Add(trigger); metadata.ScriptType = ScriptType.PowerShell; List<FunctionMetadata> functions = new List<FunctionMetadata>(); functions.Add(metadata); FunctionDescriptorProvider[] descriptorProviders = new FunctionDescriptorProvider[] { new PowerShellFunctionDescriptorProvider(scriptHostInfo.Host, scriptHostInfo.Configuration) }; var functionDescriptors = scriptHostInfo.Host.ReadFunctions(functions, descriptorProviders); Type t = FunctionGenerator.Generate("TestScriptHost", "Host.Functions", null, functionDescriptors); MethodInfo method = t.GetMethods(BindingFlags.Public | BindingFlags.Static).First(); return method; }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, bool omitInputParameter, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { return new ScriptFunctionInvoker(scriptFilePath, Config, triggerMetadata, functionMetadata, omitInputParameter, inputBindings, outputBindings); }
protected virtual Collection <ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } ParameterDescriptor triggerParameter = null; switch (triggerMetadata.Type) { case BindingType.QueueTrigger: triggerParameter = ParseQueueTrigger((QueueBindingMetadata)triggerMetadata); break; case BindingType.EventHubTrigger: triggerParameter = ParseEventHubTrigger((EventHubBindingMetadata)triggerMetadata); break; case BindingType.BlobTrigger: triggerParameter = ParseBlobTrigger((BlobBindingMetadata)triggerMetadata, typeof(Stream)); break; case BindingType.ServiceBusTrigger: triggerParameter = ParseServiceBusTrigger((ServiceBusBindingMetadata)triggerMetadata); break; case BindingType.TimerTrigger: triggerParameter = ParseTimerTrigger((TimerBindingMetadata)triggerMetadata, typeof(TimerInfo)); break; case BindingType.HttpTrigger: triggerParameter = ParseHttpTrigger((HttpTriggerBindingMetadata)triggerMetadata, typeof(HttpRequestMessage)); break; case BindingType.ManualTrigger: triggerParameter = ParseManualTrigger(triggerMetadata); break; case BindingType.ApiHubTrigger: triggerParameter = ParseApiHubTrigger((ApiHubBindingMetadata)triggerMetadata, typeof(Stream)); break; } ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); triggerParameter.IsTrigger = true; parameters.Add(triggerParameter); // Add a TraceWriter for logging parameters.Add(new ParameterDescriptor("log", typeof(TraceWriter))); // Add an IBinder to support the binding programming model parameters.Add(new ParameterDescriptor("binder", typeof(IBinder))); // Add ExecutionContext to provide access to InvocationId, etc. parameters.Add(new ParameterDescriptor("context", typeof(ExecutionContext))); return(parameters); }
protected static void ApplyMethodLevelAttributes(FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes) { if (functionMetadata.IsDisabled || (string.Compare("httptrigger", triggerMetadata.Type, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare("manualtrigger", triggerMetadata.Type, StringComparison.OrdinalIgnoreCase) == 0)) { // the function can be run manually, but there will be no automatic // triggering ConstructorInfo ctorInfo = typeof(NoAutomaticTriggerAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(ctorInfo, new object[0]); methodAttributes.Add(attributeBuilder); } }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { var inputBuffer = new BufferBlock <ScriptInvocationContext>(); _dispatcher.Register(new FunctionRegistrationContext { Metadata = functionMetadata, InputBuffer = inputBuffer }); return(new WorkerLanguageInvoker(Host, triggerMetadata, functionMetadata, _loggerFactory, inputBindings, outputBindings, inputBuffer)); }
private static MethodInfo GenerateMethod(BindingMetadata trigger) { using (var scriptHostInfo = GetScriptHostInfo()) { return GenerateMethod(trigger, scriptHostInfo); } }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { if (!(functionMetadata is ProxyFunctionMetadata proxyFunctionMetada)) { throw new InvalidCastException($"Expected {nameof(functionMetadata)} to be of type {nameof(ProxyFunctionMetadata)}"); } return(new ProxyFunctionInvoker(Host, proxyFunctionMetada, _loggerFactory)); }
protected virtual ParameterDescriptor CreateTriggerParameter(BindingMetadata triggerMetadata, Type parameterType = null) { ParameterDescriptor triggerParameter = null; TryParseTriggerParameter(triggerMetadata.Raw, out triggerParameter, parameterType); triggerParameter.IsTrigger = true; return triggerParameter; }
protected static void ApplyMethodLevelAttributes(FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes) { if (functionMetadata.IsDisabled || (triggerMetadata.Type == BindingType.HttpTrigger || triggerMetadata.Type == BindingType.ManualTrigger)) { // the function can be run manually, but there will be no automatic // triggering ConstructorInfo ctorInfo = typeof(NoAutomaticTriggerAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(ctorInfo, new object[0]); methodAttributes.Add(attributeBuilder); } }
protected static void ApplyMethodLevelAttributes(FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes) { if (functionMetadata.IsDisabled || (string.Compare("httptrigger", triggerMetadata.Type, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare("manualtrigger", triggerMetadata.Type, StringComparison.OrdinalIgnoreCase) == 0)) { // the function can be run manually, but there will be no automatic // triggering ConstructorInfo ctorInfo = typeof(NoAutomaticTriggerAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(ctorInfo, new object[0]); methodAttributes.Add(attributeBuilder); } }
protected ParameterDescriptor ParseManualTrigger(BindingMetadata trigger, Collection<CustomAttributeBuilder> methodAttributes, Type triggerParameterType = null) { if (triggerParameterType == null) { triggerParameterType = typeof(string); } ConstructorInfo ctorInfo = typeof(NoAutomaticTriggerAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(ctorInfo, new object[0]); methodAttributes.Add(attributeBuilder); string parameterName = trigger.Name; return new ParameterDescriptor(parameterName, triggerParameterType); }
protected ParameterDescriptor ParseManualTrigger(BindingMetadata trigger, Type triggerParameterType = null) { if (trigger == null) { throw new ArgumentNullException("trigger"); } if (triggerParameterType == null) { triggerParameterType = typeof(string); } return new ParameterDescriptor(trigger.Name, triggerParameterType); }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { return new ScriptFunctionInvoker(scriptFilePath, Host, functionMetadata, inputBindings, outputBindings); }
protected override async Task <Collection <ParameterDescriptor> > GetFunctionParametersAsync(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException(nameof(functionInvoker)); } if (functionMetadata == null) { throw new ArgumentNullException(nameof(functionMetadata)); } if (triggerMetadata == null) { throw new ArgumentNullException(nameof(triggerMetadata)); } if (methodAttributes == null) { throw new ArgumentNullException(nameof(methodAttributes)); } var dotNetInvoker = functionInvoker as DotNetFunctionInvoker; if (dotNetInvoker == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(DotNetFunctionInvoker).Name, functionInvoker.GetType().Name)); } try { ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); MethodInfo functionTarget = await dotNetInvoker.GetFunctionTargetAsync(); ParameterInfo[] parameters = functionTarget.GetParameters(); Collection <ParameterDescriptor> descriptors = new Collection <ParameterDescriptor>(); IEnumerable <FunctionBinding> bindings = inputBindings.Union(outputBindings); ParameterDescriptor descriptor = null; foreach (var parameter in parameters) { // Is it the trigger parameter? if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0) { ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata, parameter.ParameterType); descriptors.Add(triggerParameter); } else { Type parameterType = parameter.ParameterType; bool parameterIsByRef = parameterType.IsByRef; if (parameterIsByRef) { parameterType = parameterType.GetElementType(); } descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType); var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0); if (binding != null) { Collection <CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(parameter.ParameterType); if (customAttributes != null) { foreach (var customAttribute in customAttributes) { descriptor.CustomAttributes.Add(customAttribute); } } } if (parameter.IsOut) { descriptor.Attributes |= ParameterAttributes.Out; } descriptors.Add(descriptor); } } // Add any additional required System parameters (if they haven't already been defined by the user) if (!descriptors.Any(p => p.Type == typeof(ExecutionContext))) { // Add ExecutionContext to provide access to InvocationId, etc. descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext))); } if (TryCreateReturnValueParameterDescriptor(functionTarget.ReturnType, bindings, out descriptor)) { // If a return value binding has been specified, set up an output // binding to map it to. By convention, this is set up as the last // parameter. descriptors.Add(descriptor); } return(descriptors); } catch (AggregateException exc) { if (!(exc.InnerException is CompilationErrorException)) { throw; } } catch (CompilationErrorException) { } // We were unable to compile the function to get its signature, // setup the descriptor with the default parameters methodAttributes.Clear(); return(await base.GetFunctionParametersAsync(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings)); }
public ExtensionBinding(ScriptHostConfiguration config, ScriptBinding binding, BindingMetadata metadata) : base(config, metadata, binding.Context.Access) { _binding = binding; _attributes = _binding.GetAttributes(); }
private static bool TryParseBindingMetadata(JObject binding, out BindingMetadata bindingMetadata) { bindingMetadata = null; string bindingTypeValue = (string)binding["type"]; BindingType bindingType; if (!string.IsNullOrEmpty(bindingTypeValue) && Enum.TryParse<BindingType>(bindingTypeValue, true, out bindingType)) { switch (bindingType) { case BindingType.QueueTrigger: case BindingType.Queue: bindingMetadata = binding.ToObject<QueueBindingMetadata>(); break; case BindingType.BlobTrigger: case BindingType.Blob: bindingMetadata = binding.ToObject<BlobBindingMetadata>(); break; case BindingType.ServiceBusTrigger: case BindingType.ServiceBus: bindingMetadata = binding.ToObject<ServiceBusBindingMetadata>(); break; case BindingType.HttpTrigger: case BindingType.Http: bindingMetadata = binding.ToObject<HttpBindingMetadata>(); break; case BindingType.Table: bindingMetadata = binding.ToObject<TableBindingMetadata>(); break; case BindingType.ManualTrigger: bindingMetadata = binding.ToObject<BindingMetadata>(); break; case BindingType.TimerTrigger: bindingMetadata = binding.ToObject<TimerBindingMetadata>(); break; }; bindingMetadata.Type = bindingType; return true; } return false; }
private static MethodInfo GenerateMethod(BindingMetadata trigger) { string rootPath = Path.Combine(Environment.CurrentDirectory, @"TestScripts"); FunctionMetadata metadata = new FunctionMetadata(); metadata.Name = "Test"; metadata.Source = Path.Combine(rootPath, @"Node\Common\test.js"); metadata.InputBindings.Add(trigger); List<FunctionMetadata> metadatas = new List<FunctionMetadata>(); metadatas.Add(metadata); ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration() { RootScriptPath = rootPath }; ScriptHost host = ScriptHost.Create(scriptConfig); FunctionDescriptorProvider[] descriptorProviders = new FunctionDescriptorProvider[] { new NodeFunctionDescriptorProvider(host, scriptConfig) }; var functionDescriptors = ScriptHost.ReadFunctions(metadatas, descriptorProviders); Type t = FunctionGenerator.Generate("TestScriptHost", "Host.Functions", functionDescriptors); MethodInfo method = t.GetMethods(BindingFlags.Public | BindingFlags.Static).First(); return method; }
private ParameterDescriptor CreateTriggerParameterDescriptor(ParameterInfo parameter, BindingMetadata triggerMetadata) { ParameterDescriptor triggerParameter = null; switch (triggerMetadata.Type) { case BindingType.QueueTrigger: triggerParameter = ParseQueueTrigger((QueueBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.EventHubTrigger: triggerParameter = ParseEventHubTrigger((EventHubBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.BlobTrigger: triggerParameter = ParseBlobTrigger((BlobBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.ServiceBusTrigger: triggerParameter = ParseServiceBusTrigger((ServiceBusBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.TimerTrigger: triggerParameter = ParseTimerTrigger((TimerBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.HttpTrigger: triggerParameter = ParseHttpTrigger((HttpTriggerBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.ManualTrigger: triggerParameter = ParseManualTrigger(triggerMetadata, parameter.ParameterType); break; case BindingType.ApiHubTrigger: triggerParameter = ParseApiHubTrigger((ApiHubBindingMetadata)triggerMetadata, parameter.ParameterType); break; } triggerParameter.IsTrigger = true; return triggerParameter; }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { ICompilationService <IJavaScriptCompilation> compilationService = _compilationServiceFactory.CreateService(functionMetadata.ScriptType, functionMetadata); return(new NodeFunctionInvoker(Host, triggerMetadata, functionMetadata, inputBindings, outputBindings, compilationService)); }
protected override Collection<ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } var csharpInvoker = functionInvoker as CSharpFunctionInvoker; if (csharpInvoker == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(CSharpFunctionInvoker).Name, functionInvoker.GetType().Name)); } try { ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); MethodInfo functionTarget = csharpInvoker.GetFunctionTargetAsync().Result; ParameterInfo[] parameters = functionTarget.GetParameters(); Collection<ParameterDescriptor> descriptors = new Collection<ParameterDescriptor>(); IEnumerable<FunctionBinding> bindings = inputBindings.Union(outputBindings); bool addHttpRequestSystemParameter = false; foreach (var parameter in parameters) { // Is it the trigger parameter? if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0) { descriptors.Add(CreateTriggerParameterDescriptor(parameter, triggerMetadata)); if (triggerMetadata.Type == BindingType.HttpTrigger && parameter.ParameterType != typeof(HttpRequestMessage)) { addHttpRequestSystemParameter = true; } } else { Type parameterType = parameter.ParameterType; if (parameterType.IsByRef) { parameterType = parameterType.GetElementType(); } var descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType); var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0); if (binding != null) { Collection<CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(); if (customAttributes != null) { foreach (var customAttribute in customAttributes) { descriptor.CustomAttributes.Add(customAttribute); } } } if (parameter.IsOut) { descriptor.Attributes |= ParameterAttributes.Out; } descriptors.Add(descriptor); } } // Add any additional common System parameters // Add ExecutionContext to provide access to InvocationId, etc. descriptors.Add(new ParameterDescriptor("context", typeof(ExecutionContext))); // If we have an HTTP trigger binding but we're not binding // to the HttpRequestMessage, require it as a system parameter if (addHttpRequestSystemParameter) { descriptors.Add(new ParameterDescriptor(ScriptConstants.DefaultSystemTriggerParameterName, typeof(HttpRequestMessage))); } return descriptors; } catch (AggregateException exc) { if (!(exc.InnerException is CompilationErrorException)) { throw; } } catch (CompilationErrorException) { } // We were unable to compile the function to get its signature, // setup the descriptor with the default parameters return base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings); }
public HttpBinding(ScriptHostConfiguration config, BindingMetadata metadata, FileAccess access) : base(config, metadata, access) { }
protected override async Task <Collection <ParameterDescriptor> > GetFunctionParametersAsync(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { var parameters = await base.GetFunctionParametersAsync(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings); var bindings = inputBindings.Union(outputBindings); try { var triggerHandlesReturnValueBinding = bindings.SingleOrDefault(b => b.Metadata.IsTrigger && (b as ExtensionBinding)?.Attributes.SingleOrDefault(a => (a.GetType().GetCustomAttribute(typeof(BindingAttribute)) as BindingAttribute)?.TriggerHandlesReturnValue == true) != null); if (triggerHandlesReturnValueBinding != null) { var byRefType = typeof(object).MakeByRefType(); ParameterDescriptor returnDescriptor = new ParameterDescriptor(ScriptConstants.SystemReturnParameterName, byRefType); returnDescriptor.Attributes |= ParameterAttributes.Out; Collection <CustomAttributeBuilder> customAttributes = triggerHandlesReturnValueBinding.GetCustomAttributes(byRefType); if (customAttributes != null) { foreach (var customAttribute in customAttributes) { returnDescriptor.CustomAttributes.Add(customAttribute); } } parameters.Add(returnDescriptor); } } catch (InvalidOperationException ex) { throw new InvalidOperationException("Multiple bindings cannot be designated as HandlesReturnValue.", ex); } return(parameters); }
private ParameterDescriptor CreateTriggerParameterDescriptor(ParameterInfo parameter, BindingMetadata triggerMetadata) { ParameterDescriptor triggerParameter = null; switch (triggerMetadata.Type) { case BindingType.QueueTrigger: triggerParameter = ParseQueueTrigger((QueueBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.EventHubTrigger: triggerParameter = ParseEventHubTrigger((EventHubBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.BlobTrigger: triggerParameter = ParseBlobTrigger((BlobBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.ServiceBusTrigger: triggerParameter = ParseServiceBusTrigger((ServiceBusBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.TimerTrigger: triggerParameter = ParseTimerTrigger((TimerBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.HttpTrigger: triggerParameter = ParseHttpTrigger((HttpTriggerBindingMetadata)triggerMetadata, parameter.ParameterType); break; case BindingType.ManualTrigger: triggerParameter = ParseManualTrigger(triggerMetadata, parameter.ParameterType); break; case BindingType.ApiHubTrigger: triggerParameter = ParseApiHubTrigger((ApiHubBindingMetadata)triggerMetadata, parameter.ParameterType); break; } triggerParameter.IsTrigger = true; return(triggerParameter); }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { return(new ProxyFunctionInvoker(Host, functionMetadata, _proxyClient)); }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { return(new CSharpFunctionInvoker(Host, functionMetadata, inputBindings, outputBindings, new FunctionEntryPointResolver(), _assemblyLoader)); }
protected override Collection <ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } var dotNetInvoker = functionInvoker as DotNetFunctionInvoker; if (dotNetInvoker == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(DotNetFunctionInvoker).Name, functionInvoker.GetType().Name)); } try { ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); MethodInfo functionTarget = dotNetInvoker.GetFunctionTargetAsync().Result; ParameterInfo[] parameters = functionTarget.GetParameters(); Collection <ParameterDescriptor> descriptors = new Collection <ParameterDescriptor>(); IEnumerable <FunctionBinding> bindings = inputBindings.Union(outputBindings); ParameterDescriptor descriptor = null; foreach (var parameter in parameters) { // Is it the trigger parameter? if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0) { ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata, parameter.ParameterType); descriptors.Add(triggerParameter); } else { Type parameterType = parameter.ParameterType; bool parameterIsByRef = parameterType.IsByRef; if (parameterIsByRef) { parameterType = parameterType.GetElementType(); } descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType); var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0); if (binding != null) { Collection <CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(parameter.ParameterType); if (customAttributes != null) { foreach (var customAttribute in customAttributes) { descriptor.CustomAttributes.Add(customAttribute); } } } // In the C# programming model, IsOut is set for out parameters // In the F# programming model, neither IsOut nor IsIn are set for byref parameters (which are used as out parameters). // Justification for this cariation of the programming model is that declaring 'out' parameters is (deliberately) // awkward in F#, they require opening System.Runtime.InteropServices and adding the [<Out>] attribute, and using // a byref parameter. In contrast declaring a byref parameter alone (neither labelled In nor Out) is simple enough. if (parameter.IsOut || (functionMetadata.ScriptType == ScriptType.FSharp && parameterIsByRef && !parameter.IsIn)) { descriptor.Attributes |= ParameterAttributes.Out; } descriptors.Add(descriptor); } } // Add any additional required System parameters (if they haven't already been defined by the user) if (!descriptors.Any(p => p.Type == typeof(ExecutionContext))) { // Add ExecutionContext to provide access to InvocationId, etc. descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext))); } if (TryCreateReturnValueParameterDescriptor(functionTarget.ReturnType, bindings, out descriptor)) { // If a return value binding has been specified, set up an output // binding to map it to. By convention, this is set up as the last // parameter. descriptors.Add(descriptor); } return(descriptors); } catch (AggregateException exc) { if (!(exc.InnerException is CompilationErrorException)) { throw; } } catch (CompilationErrorException) { } // We were unable to compile the function to get its signature, // setup the descriptor with the default parameters methodAttributes.Clear(); return(base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings)); }
protected override Collection <ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } var csharpInvoker = functionInvoker as CSharpFunctionInvoker; if (csharpInvoker == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(CSharpFunctionInvoker).Name, functionInvoker.GetType().Name)); } try { ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); MethodInfo functionTarget = csharpInvoker.GetFunctionTargetAsync().Result; ParameterInfo[] parameters = functionTarget.GetParameters(); Collection <ParameterDescriptor> descriptors = new Collection <ParameterDescriptor>(); IEnumerable <FunctionBinding> bindings = inputBindings.Union(outputBindings); bool addHttpRequestSystemParameter = false; foreach (var parameter in parameters) { // Is it the trigger parameter? if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0) { descriptors.Add(CreateTriggerParameterDescriptor(parameter, triggerMetadata)); if (triggerMetadata.Type == BindingType.HttpTrigger && parameter.ParameterType != typeof(HttpRequestMessage)) { addHttpRequestSystemParameter = true; } } else { Type parameterType = parameter.ParameterType; if (parameterType.IsByRef) { parameterType = parameterType.GetElementType(); } var descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType); var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0); if (binding != null) { Collection <CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(); if (customAttributes != null) { foreach (var customAttribute in customAttributes) { descriptor.CustomAttributes.Add(customAttribute); } } } if (parameter.IsOut) { descriptor.Attributes |= ParameterAttributes.Out; } descriptors.Add(descriptor); } } // Add any additional common System parameters // Add ExecutionContext to provide access to InvocationId, etc. descriptors.Add(new ParameterDescriptor("context", typeof(ExecutionContext))); // If we have an HTTP trigger binding but we're not binding // to the HttpRequestMessage, require it as a system parameter if (addHttpRequestSystemParameter) { descriptors.Add(new ParameterDescriptor(ScriptConstants.DefaultSystemTriggerParameterName, typeof(HttpRequestMessage))); } return(descriptors); } catch (AggregateException exc) { if (!(exc.InnerException is CompilationErrorException)) { throw; } } catch (CompilationErrorException) { } // We were unable to compile the function to get its signature, // setup the descriptor with the default parameters return(base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings)); }
internal ScriptFunctionInvoker(string scriptFilePath, ScriptHostConfiguration config, BindingMetadata trigger, FunctionMetadata functionMetadata, bool omitInputParameter, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { _scriptFilePath = scriptFilePath; _config = config; _scriptType = Path.GetExtension(_scriptFilePath).ToLower().TrimStart('.'); _inputBindings = inputBindings; _outputBindings = outputBindings; _functionName = functionMetadata.Name; _omitInputParameter = omitInputParameter; _trigger = trigger; if (config.FileLoggingEnabled) { string logFilePath = Path.Combine(_config.RootLogPath, "Function", _functionName); _fileTraceWriter = new FileTraceWriter(logFilePath, TraceLevel.Verbose); } else { _fileTraceWriter = NullTraceWriter.Instance; } }
protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { return(new WorkerFunctionInvoker(Host, triggerMetadata, functionMetadata, _loggerFactory, inputBindings, outputBindings, _dispatcher, _applicationLifetime, _workerInitializationTimeout)); }
protected abstract IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings);
public virtual bool TryCreate(FunctionMetadata functionMetadata, out FunctionDescriptor functionDescriptor) { functionDescriptor = null; if (functionMetadata.IsDisabled) { return(false); } // parse the bindings Collection <FunctionBinding> inputBindings = FunctionBinding.GetBindings(Config, functionMetadata.InputBindings, FileAccess.Read); Collection <FunctionBinding> outputBindings = FunctionBinding.GetBindings(Config, functionMetadata.OutputBindings, FileAccess.Write); BindingMetadata triggerMetadata = functionMetadata.InputBindings.FirstOrDefault(p => p.IsTrigger); BindingType triggerType = triggerMetadata.Type; string triggerParameterName = triggerMetadata.Name; bool triggerNameSpecified = true; if (string.IsNullOrEmpty(triggerParameterName)) { // default the name to simply 'input' triggerMetadata.Name = triggerParameterName = "input"; triggerNameSpecified = false; } Collection <CustomAttributeBuilder> methodAttributes = new Collection <CustomAttributeBuilder>(); ParameterDescriptor triggerParameter = null; bool omitInputParameter = false; switch (triggerType) { case BindingType.QueueTrigger: triggerParameter = ParseQueueTrigger((QueueBindingMetadata)triggerMetadata); break; case BindingType.BlobTrigger: triggerParameter = ParseBlobTrigger((BlobBindingMetadata)triggerMetadata); break; case BindingType.ServiceBusTrigger: triggerParameter = ParseServiceBusTrigger((ServiceBusBindingMetadata)triggerMetadata); break; case BindingType.TimerTrigger: omitInputParameter = true; triggerParameter = ParseTimerTrigger((TimerBindingMetadata)triggerMetadata, typeof(TimerInfo)); break; case BindingType.HttpTrigger: if (!triggerNameSpecified) { triggerMetadata.Name = triggerParameterName = "req"; } triggerParameter = ParseHttpTrigger((HttpBindingMetadata)triggerMetadata, methodAttributes, typeof(HttpRequestMessage)); break; case BindingType.ManualTrigger: triggerParameter = ParseManualTrigger(triggerMetadata, methodAttributes); break; } Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); triggerParameter.IsTrigger = true; parameters.Add(triggerParameter); // Add a TraceWriter for logging parameters.Add(new ParameterDescriptor("log", typeof(TraceWriter))); // Add an IBinder to support the binding programming model parameters.Add(new ParameterDescriptor("binder", typeof(IBinder))); // Add ExecutionContext to provide access to InvocationId, etc. parameters.Add(new ParameterDescriptor("context", typeof(ExecutionContext))); string scriptFilePath = Path.Combine(Config.RootScriptPath, functionMetadata.Source); IFunctionInvoker invoker = CreateFunctionInvoker(scriptFilePath, triggerMetadata, functionMetadata, omitInputParameter, inputBindings, outputBindings); functionDescriptor = new FunctionDescriptor(functionMetadata.Name, invoker, functionMetadata, parameters, methodAttributes); return(true); }
protected virtual Task <Collection <ParameterDescriptor> > GetFunctionParametersAsync(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata, BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings) { if (functionInvoker == null) { throw new ArgumentNullException("functionInvoker"); } if (functionMetadata == null) { throw new ArgumentNullException("functionMetadata"); } if (triggerMetadata == null) { throw new ArgumentNullException("triggerMetadata"); } if (methodAttributes == null) { throw new ArgumentNullException("methodAttributes"); } ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes); Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata); parameters.Add(triggerParameter); // Add an IBinder to support the binding programming model parameters.Add(new ParameterDescriptor(ScriptConstants.SystemBinderParameterName, typeof(IBinder))); // Add ExecutionContext to provide access to InvocationId, etc. parameters.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext))); parameters.Add(new ParameterDescriptor(ScriptConstants.SystemLoggerParameterName, typeof(ILogger))); return(Task.FromResult(parameters)); }
public void ValidateBinding_InvalidName_Throws(string bindingName) { BindingMetadata bindingMetadata = new BindingMetadata { Name = bindingName }; var ex = Assert.Throws<ArgumentException>(() => { _provider.ValidateBinding(bindingMetadata); }); Assert.Equal($"The binding name {bindingName} is invalid. Please assign a valid name to the binding.", ex.Message); }