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));
 }
예제 #10
0
 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));
 }
예제 #13
0
 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);
예제 #16
0
 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);
        }
예제 #24
0
 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);
     }
 }
예제 #25
0
        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);
     }
 }
예제 #27
0
 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;
        }
예제 #39
0
        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);
        }
예제 #44
0
 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));
 }
예제 #46
0
        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;
            }
        }
예제 #49
0
 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));
 }
예제 #50
0
 protected abstract IFunctionInvoker CreateFunctionInvoker(string scriptFilePath, BindingMetadata triggerMetadata, FunctionMetadata functionMetadata, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings);
예제 #51
0
        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);
        }
예제 #52
0
        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);
        }