internal static FunctionLoadResponse FunctionLoadRequestHandler(FunctionLoadRequest request, IFunctionsApplication application, IMethodInfoLocator methodInfoLocator) { var response = new FunctionLoadResponse { FunctionId = request.FunctionId, Result = StatusResult.Success }; if (!request.Metadata.IsProxy) { try { FunctionDefinition definition = request.ToFunctionDefinition(methodInfoLocator); application.LoadFunction(definition); } catch (Exception ex) { response.Result = new StatusResult { Status = StatusResult.Types.Status.Failure, Exception = ex.ToRpcException() }; } } return(response); }
internal StreamingMessage ProcessFunctionLoadRequest(StreamingMessage request) { FunctionLoadRequest functionLoadRequest = request.FunctionLoadRequest; StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.FunctionLoadResponse, out StatusResult status); response.FunctionLoadResponse.FunctionId = functionLoadRequest.FunctionId; try { // Try loading the metadata of the function _functionLoader.Load(functionLoadRequest); // if we haven't yet, add the well-known Function App module path to the PSModulePath // The location of this module path is in a folder called "Modules" in the root of the Function App. if (!_prependedPath) { string functionAppModulesPath = Path.GetFullPath( Path.Combine(functionLoadRequest.Metadata.Directory, "..", "Modules")); _powerShellManager.PrependToPSModulePath(functionAppModulesPath); _prependedPath = true; } } catch (Exception e) { status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); } return(response); }
public FunctionLoaderTests() { _functionDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestScripts", "Function"); var functionId = Guid.NewGuid().ToString(); var metadata = new RpcFunctionMetadata { Name = "MyHttpTrigger", Directory = _functionDirectory, Bindings = { { "req", new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "httpTrigger" } }, { "inputBlob", new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "blobTrigger" } }, { "res", new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "http" } } } }; _functionLoadRequest = new FunctionLoadRequest { FunctionId = functionId, Metadata = metadata }; }
internal void SendFunctionLoadRequest(FunctionRegistrationContext context) { FunctionMetadata metadata = context.Metadata; // associate the invocation input buffer with the function _functionInputBuffers[context.Metadata.FunctionId] = context.InputBuffer; // send a load request for the registered function FunctionLoadRequest request = new FunctionLoadRequest() { FunctionId = metadata.FunctionId, Metadata = new RpcFunctionMetadata() { Name = metadata.Name, Directory = metadata.FunctionDirectory ?? string.Empty, EntryPoint = metadata.EntryPoint ?? string.Empty, ScriptFile = metadata.ScriptFile ?? string.Empty } }; foreach (var binding in metadata.Bindings) { BindingInfo bindingInfo = binding.ToBindingInfo(); request.Metadata.Bindings.Add(binding.Name, bindingInfo); } SendStreamingMessage(new StreamingMessage { FunctionLoadRequest = request }); }
internal StreamingMessage ProcessFunctionLoadRequest(StreamingMessage request) { FunctionLoadRequest functionLoadRequest = request.FunctionLoadRequest; // Assume success unless something bad happens StatusResult status = new StatusResult() { Status = StatusResult.Types.Status.Success }; // Try to load the functions try { _functionLoader.Load(functionLoadRequest); } catch (Exception e) { status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); } return(new StreamingMessage() { RequestId = request.RequestId, FunctionLoadResponse = new FunctionLoadResponse() { FunctionId = functionLoadRequest.FunctionId, Result = status } }); }
static PowerShellManagerTests() { s_funcDirectory = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "TestScripts", "PowerShell"); s_testLogger = new ConsoleLogger(); s_testInputData = new List <ParameterBinding> { new ParameterBinding { Name = TestInputBindingName, Data = new TypedData { String = TestStringData } } }; var rpcFunctionMetadata = new RpcFunctionMetadata() { Name = "TestFuncApp", Directory = s_funcDirectory, Bindings = { { TestInputBindingName, new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "httpTrigger" } }, { TestOutputBindingName, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "http" } } } }; s_functionLoadRequest = new FunctionLoadRequest { FunctionId = "FunctionId", Metadata = rpcFunctionMetadata }; FunctionLoader.SetupWellKnownPaths(s_functionLoadRequest, managedDependenciesPath: null); }
/// <summary> /// Setup the well known paths about the FunctionApp. /// This method is called only once during the code start. /// </summary> internal static void SetupWellKnownPaths(FunctionLoadRequest request) { // Resolve the FunctionApp root path FunctionAppRootPath = Path.GetFullPath(Path.Join(request.Metadata.Directory, "..")); // Resolve module paths var appLevelModulesPath = Path.Join(FunctionAppRootPath, "Modules"); var workerLevelModulesPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Modules"); FunctionModulePath = $"{appLevelModulesPath}{Path.PathSeparator}{workerLevelModulesPath}"; // Add the managed dependencies folder path if (DependencyManager.DependenciesPath != null) { FunctionModulePath = $"{DependencyManager.DependenciesPath}{Path.PathSeparator}{FunctionModulePath}"; } // Resolve the FunctionApp profile path var options = new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive }; var profiles = Directory.EnumerateFiles(FunctionAppRootPath, "profile.ps1", options); FunctionAppProfilePath = profiles.FirstOrDefault(); }
internal FunctionLoadRequest GetFunctionLoadRequest(FunctionMetadata metadata, ManagedDependencyOptions managedDependencyOptions) { FunctionLoadRequest request = new FunctionLoadRequest() { FunctionId = metadata.FunctionId, Metadata = new RpcFunctionMetadata() { Name = metadata.Name, Directory = metadata.FunctionDirectory ?? string.Empty, EntryPoint = metadata.EntryPoint ?? string.Empty, ScriptFile = metadata.ScriptFile ?? string.Empty, IsProxy = metadata.IsProxy } }; if (managedDependencyOptions != null && managedDependencyOptions.Enabled) { _workerChannelLogger?.LogDebug($"Adding dependency download request to {_workerConfig.Description.Language} language worker"); request.ManagedDependencyEnabled = managedDependencyOptions.Enabled; } foreach (var binding in metadata.Bindings) { BindingInfo bindingInfo = binding.ToBindingInfo(); request.Metadata.Bindings.Add(binding.Name, bindingInfo); } return(request); }
public GrpcFunctionMetadata(FunctionLoadRequest loadRequest) { EntryPoint = loadRequest.Metadata.EntryPoint; Name = loadRequest.Metadata.Name; PathToAssembly = Path.GetFullPath(loadRequest.Metadata.ScriptFile); FunctionId = loadRequest.FunctionId; }
internal void SendFunctionLoadRequest(FunctionMetadata metadata) { // send a load request for the registered function FunctionLoadRequest request = new FunctionLoadRequest() { FunctionId = metadata.FunctionId, Metadata = new RpcFunctionMetadata() { Name = metadata.Name, Directory = metadata.FunctionDirectory ?? string.Empty, EntryPoint = metadata.EntryPoint ?? string.Empty, ScriptFile = metadata.ScriptFile ?? string.Empty } }; if (_managedDependencyOptions?.Value != null && _managedDependencyOptions.Value.Enabled) { _workerChannelLogger?.LogDebug($"Adding dependency download request to {_workerConfig.Language} language worker"); request.ManagedDependencyEnabled = _managedDependencyOptions.Value.Enabled; } foreach (var binding in metadata.Bindings) { BindingInfo bindingInfo = binding.ToBindingInfo(); request.Metadata.Bindings.Add(binding.Name, bindingInfo); } SendStreamingMessage(new StreamingMessage { FunctionLoadRequest = request }); }
public void Register(FunctionRegistrationContext context) { FunctionMetadata metadata = context.Metadata; // associate the invocation input buffer with the function _functionInputBuffers[context.Metadata.FunctionId] = context.InputBuffer; // send a load request for the registered function FunctionLoadRequest request = new FunctionLoadRequest() { FunctionId = metadata.FunctionId, Metadata = new RpcFunctionMetadata() { Name = metadata.Name, Directory = metadata.FunctionDirectory, EntryPoint = metadata.EntryPoint ?? string.Empty, ScriptFile = metadata.ScriptFile ?? string.Empty } }; foreach (var binding in metadata.Bindings) { request.Metadata.Bindings.Add(binding.Name, new BindingInfo { Direction = (BindingInfo.Types.Direction)binding.Direction, Type = binding.Type }); } Send(new StreamingMessage { FunctionLoadRequest = request }); }
/// <summary> /// Method to process a FunctionLoadRequest. /// FunctionLoadRequest should be processed sequentially. There is no point to process FunctionLoadRequest /// concurrently as a FunctionApp doesn't include a lot functions in general. Having this step sequential /// will make the Runspace-level initialization easier and more predictable. /// </summary> internal StreamingMessage ProcessFunctionLoadRequest(StreamingMessage request) { FunctionLoadRequest functionLoadRequest = request.FunctionLoadRequest; StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.FunctionLoadResponse, out StatusResult status); response.FunctionLoadResponse.FunctionId = functionLoadRequest.FunctionId; try { // Ideally, the initialization should happen when processing 'WorkerInitRequest', however, the 'WorkerInitRequest' // message doesn't provide the file path of the FunctionApp. That information is not available until the first // 'FunctionLoadRequest' comes in. Therefore, we run initialization here. if (!_isFunctionAppInitialized) { FunctionLoader.SetupWellKnownPaths(functionLoadRequest); _powershellPool.Initialize(request.RequestId); _isFunctionAppInitialized = true; } // Load the metadata of the function. _functionLoader.LoadFunction(functionLoadRequest); } catch (Exception e) { status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); } return(response); }
public void Creates() { var bindingInfoProvider = new DefaultOutputBindingsInfoProvider(); var methodInfoLocator = new DefaultMethodInfoLocator(); string fullPathToThisAssembly = GetType().Assembly.Location; var functionLoadRequest = new FunctionLoadRequest { FunctionId = "abc", Metadata = new RpcFunctionMetadata { EntryPoint = $"Microsoft.Azure.Functions.Worker.Tests.{nameof(GrpcFunctionDefinitionTests)}+{nameof(MyFunctionClass)}.{nameof(MyFunctionClass.Run)}", ScriptFile = Path.GetFileName(fullPathToThisAssembly), Name = "myfunction" } }; // We base this on the request exclusively, not the binding attributes. functionLoadRequest.Metadata.Bindings.Add("req", new BindingInfo { Type = "HttpTrigger", Direction = Direction.In }); functionLoadRequest.Metadata.Bindings.Add("$return", new BindingInfo { Type = "Http", Direction = Direction.Out }); FunctionDefinition definition = functionLoadRequest.ToFunctionDefinition(methodInfoLocator); Assert.Equal(functionLoadRequest.FunctionId, definition.Id); Assert.Equal(functionLoadRequest.Metadata.EntryPoint, definition.EntryPoint); Assert.Equal(functionLoadRequest.Metadata.Name, definition.Name); Assert.Equal(fullPathToThisAssembly, definition.PathToAssembly); // Parameters Assert.Collection(definition.Parameters, p => { Assert.Equal("req", p.Name); Assert.Equal(typeof(HttpRequestData), p.Type); }); // InputBindings Assert.Collection(definition.InputBindings, p => { Assert.Equal("req", p.Key); Assert.Equal(BindingDirection.In, p.Value.Direction); Assert.Equal("HttpTrigger", p.Value.Type); }); // OutputBindings Assert.Collection(definition.OutputBindings, p => { Assert.Equal("$return", p.Key); Assert.Equal(BindingDirection.Out, p.Value.Direction); Assert.Equal("Http", p.Value.Type); }); }
/// <summary> /// Method to process a FunctionLoadRequest. /// FunctionLoadRequest should be processed sequentially. There is no point to process FunctionLoadRequest /// concurrently as a FunctionApp doesn't include a lot functions in general. Having this step sequential /// will make the Runspace-level initialization easier and more predictable. /// </summary> internal StreamingMessage ProcessFunctionLoadRequest(StreamingMessage request) { FunctionLoadRequest functionLoadRequest = request.FunctionLoadRequest; StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.FunctionLoadResponse, out StatusResult status); response.FunctionLoadResponse.FunctionId = functionLoadRequest.FunctionId; // When a functionLoadRequest comes in, we check to see if a dependency download has failed in a previous call // or if PowerShell could not be initialized. If this is the case, mark this as a failed request // and submit the exception to the Host (runtime). if (_initTerminatingError != null) { status.Status = StatusResult.Types.Status.Failure; status.Exception = _initTerminatingError.ToRpcException(); return(response); } // Ideally, the initialization should happen when processing 'WorkerInitRequest', however, the 'WorkerInitRequest' // message doesn't provide information about the FunctionApp. That information is not available until the first // 'FunctionLoadRequest' comes in. Therefore, we run initialization here. if (!_isFunctionAppInitialized) { try { _isFunctionAppInitialized = true; InitializeForFunctionApp(request, response); } catch (Exception e) { // Failure that happens during this step is terminating and we will need to return a failure response to // all subsequent 'FunctionLoadRequest'. Cache the exception so we can reuse it in future calls. _initTerminatingError = e; status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); return(response); } } try { // Load the metadata of the function. _functionLoader.LoadFunction(functionLoadRequest); } catch (Exception e) { status.Status = StatusResult.Types.Status.Failure; status.Exception = e.ToRpcException(); } return(response); }
public void AddFunction(FunctionLoadRequest functionLoadRequest) { FunctionDefinition functionDefinition = _functionDescriptorFactory.Create(functionLoadRequest); if (functionDefinition.Metadata.FunctionId is null) { throw new InvalidOperationException("The function ID for the current load request is invalid"); } _functionMap.TryAdd(functionDefinition.Metadata.FunctionId, functionDefinition); }
/// <summary> /// Initializes the dependency manger and performs the following: /// - Parse functionAppRoot\requirements.psd1 file and create a list of dependencies to install. /// - Set the DependenciesPath which gets used in 'SetupWellKnownPaths'. /// - Determines if the dependency module needs to be installed by checking the latest available version /// in the PSGallery and the destination path (to see if it is already installed). /// - Set the destination path (if running in Azure vs local) where the function app dependencies will be installed. /// </summary> internal void Initialize(FunctionLoadRequest request) { if (!request.ManagedDependencyEnabled) { return; } try { // Resolve the FunctionApp root path. var functionAppRootPath = Path.GetFullPath(Path.Join(request.Metadata.Directory, "..")); // Resolve the managed dependencies installation path. DependenciesPath = GetManagedDependenciesPath(functionAppRootPath); // Parse and process the function app dependencies defined in requirements.psd1. Hashtable entries = ParsePowerShellDataFile(functionAppRootPath, RequirementsPsd1FileName); foreach (DictionaryEntry entry in entries) { // A valid entry is of the form: 'ModuleName'='MajorVersion.*" string name = (string)entry.Key; string version = (string)entry.Value; // Validates that the module name is a supported dependency. ValidateModuleName(name); // Validate the module version. string majorVersion = GetMajorVersion(version); string latestVersion = DependencyManagementUtils.GetModuleLatestSupportedVersion(name, majorVersion); ValidateModuleMajorVersion(name, majorVersion, latestVersion); // Before installing the module, check the path to see if it is already installed. var moduleVersionFolderPath = Path.Combine(DependenciesPath, name, latestVersion); if (!Directory.Exists(moduleVersionFolderPath)) { _shouldUpdateFunctionAppDependencies = true; } // Create a DependencyInfo object and add it to the list of dependencies to install. var dependencyInfo = new DependencyInfo(name, majorVersion, latestVersion); Dependencies.Add(dependencyInfo); } } catch (Exception e) { // Reset DependenciesPath and Dependencies. DependenciesPath = null; Dependencies.Clear(); var errorMsg = string.Format(PowerShellWorkerStrings.FailToInstallFuncAppDependencies, e.Message); throw new DependencyInstallationException(errorMsg, e); } }
/// <summary> /// Setup the well known paths about the FunctionApp. /// This method is called only once during the code start. /// </summary> internal static void SetupWellKnownPaths(FunctionLoadRequest request) { FunctionAppRootPath = Path.GetFullPath(Path.Join(request.Metadata.Directory, "..")); FunctionAppModulesPath = Path.Join(FunctionAppRootPath, "Modules"); var options = new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive }; var profiles = Directory.EnumerateFiles(FunctionAppRootPath, "profile.ps1", options); FunctionAppProfilePath = profiles.FirstOrDefault(); }
internal void FunctionLoadRequestHandler(StreamingMessage request) { FunctionLoadRequest functionLoadRequest = request.FunctionLoadRequest; StreamingMessage response = NewStreamingMessageTemplate( request.RequestId, StreamingMessage.ContentOneofCase.FunctionLoadResponse, out StatusResult status); response.FunctionLoadResponse.FunctionId = functionLoadRequest.FunctionId; _blockingCollectionQueue.Add(response); }
private void SetupAppRootPathAndModulePath(FunctionLoadRequest functionLoadRequest, string managedDependenciesPath) { FunctionLoader.SetupWellKnownPaths(functionLoadRequest, managedDependenciesPath); if (FunctionLoader.FunctionAppRootPath == null) { throw new InvalidOperationException(PowerShellWorkerStrings.FunctionAppRootNotResolved); } _firstPwshInstance.AddCommand("Microsoft.PowerShell.Management\\Set-Content") .AddParameter("Path", "env:PSModulePath") .AddParameter("Value", FunctionLoader.FunctionModulePath) .InvokeAndClearCommands(); }
private FunctionLoadRequest GetFuncLoadRequest(string functionAppRoot, bool managedDependencyEnabled) { var metadata = new RpcFunctionMetadata { Name = "MyHttpTrigger", Directory = functionAppRoot }; var functionLoadRequest = new FunctionLoadRequest { FunctionId = _functionId, Metadata = metadata }; functionLoadRequest.ManagedDependencyEnabled = managedDependencyEnabled; return(functionLoadRequest); }
static TestUtils() { FunctionDirectory = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "TestScripts", "PowerShell"); RpcFunctionMetadata = new RpcFunctionMetadata() { Name = "TestFuncApp", Directory = FunctionDirectory, Bindings = { { TestInputBindingName , new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "httpTrigger" } }, { TestOutputBindingName, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "http" } } } }; FunctionLoadRequest = new FunctionLoadRequest {FunctionId = "FunctionId", Metadata = RpcFunctionMetadata}; FunctionLoader.SetupWellKnownPaths(FunctionLoadRequest); }
private static async Task HandleFunctionLoadRequest(FunctionLoadRequest loadRequest) { s_loadedFunctions.TryAdd(loadRequest.FunctionId, loadRequest.Metadata); var response = new StreamingMessage() { RequestId = s_requestId, FunctionLoadResponse = new FunctionLoadResponse() { FunctionId = loadRequest.FunctionId, Result = new StatusResult() { Status = StatusResult.Types.Status.Success } } }; await s_call.RequestStream.WriteAsync(response); }
public Task <FunctionLoadResponse> LoadFunctionAsync(FunctionLoadRequest request) { // instead, use request.Metadata.IsProxy if (!string.IsNullOrEmpty(request.Metadata?.ScriptFile)) { _functionBroker.AddFunction(request); } var response = new FunctionLoadResponse { FunctionId = request.FunctionId, Result = new StatusResult { Status = Status.Success } }; return(Task.FromResult(response)); }
public FunctionDefinition Create(FunctionLoadRequest request) { FunctionMetadata metadata = request.ToFunctionMetadata(); if (metadata.PathToAssembly == null) { throw new InvalidOperationException("The path to the function assembly is null."); } if (metadata.EntryPoint == null) { throw new InvalidOperationException("The entry point is null."); } var entryPointMatch = _entryPointRegex.Match(metadata.EntryPoint); if (!entryPointMatch.Success) { throw new InvalidOperationException("Invalid entry point configuration. The function entry point must be defined in the format <fulltypename>.<methodname>"); } string typeName = entryPointMatch.Groups["typename"].Value; string methodName = entryPointMatch.Groups["methodname"].Value; Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.PathToAssembly); Type?functionType = assembly.GetType(typeName); MethodInfo?methodInfo = functionType?.GetMethod(methodName); if (methodInfo == null) { throw new InvalidOperationException($"Method '{methodName}' specified in {nameof(FunctionMetadata.EntryPoint)} was not found. This function cannot be created."); } IFunctionInvoker invoker = _functionInvokerFactory.Create(methodInfo); IEnumerable <FunctionParameter> parameters = methodInfo.GetParameters() .Where(p => p.Name != null) .Select(p => new FunctionParameter(p.Name !, p.ParameterType)); return(new DefaultFunctionDefinition(metadata, invoker, parameters)); }
public void TestFunctionLoaderGetInfo() { var functionId = Guid.NewGuid().ToString(); var directory = "/Users/tylerleonhardt/Desktop/Tech/PowerShell/AzureFunctions/azure-functions-powershell-worker/examples/PSCoreApp/MyHttpTrigger"; var scriptPathExpected = $"{directory}/run.ps1"; var name = "MyHttpTrigger"; var metadata = new RpcFunctionMetadata { Name = name, EntryPoint = "", Directory = directory, ScriptFile = scriptPathExpected }; metadata.Bindings.Add("req", new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "httpTrigger" }); metadata.Bindings.Add("res", new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "http" }); var functionLoadRequest = new FunctionLoadRequest { FunctionId = functionId, Metadata = metadata }; var functionLoader = new FunctionLoader(); functionLoader.Load(functionLoadRequest); var funcInfo = functionLoader.GetFunctionInfo(functionId); Assert.Equal(directory, funcInfo.Directory); Assert.Equal(name, funcInfo.FunctionName); Assert.Equal(2, funcInfo.AllBindings.Count); Assert.Single(funcInfo.OutputBindings); }
static HelperModuleTests() { var funcDirectory = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "TestScripts", "PowerShell"); var rpcFuncMetadata = new RpcFunctionMetadata() { Name = "TestFuncApp", Directory = funcDirectory, ScriptFile = Path.Join(funcDirectory, "testBasicFunction.ps1"), EntryPoint = string.Empty, Bindings = { { "req", new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "httpTrigger" } }, { Response, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "http" } }, { Queue, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "queue" } }, { Foo, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "new" } }, { Bar, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "new" } }, { Food, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "new" } } } }; var funcLoadReq = new FunctionLoadRequest { FunctionId = "FunctionId", Metadata = rpcFuncMetadata }; FunctionLoader.SetupWellKnownPaths(funcLoadReq); s_pwsh = Utils.NewPwshInstance(); s_funcInfo = new AzFunctionInfo(rpcFuncMetadata); }
public void TestFunctionLoaderGetFuncWithEntryPoint() { var functionId = Guid.NewGuid().ToString(); var directory = "/Users/azure/PSCoreApp/MyHttpTrigger"; var scriptPathExpected = $"{directory}/run.ps1"; var entryPointExpected = "Foo"; var metadata = new RpcFunctionMetadata { Name = "MyHttpTrigger", EntryPoint = entryPointExpected, Directory = directory, ScriptFile = scriptPathExpected }; metadata.Bindings.Add("req", new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "httpTrigger" }); metadata.Bindings.Add("res", new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "http" }); var functionLoadRequest = new FunctionLoadRequest { FunctionId = functionId, Metadata = metadata }; var functionLoader = new FunctionLoader(); functionLoader.Load(functionLoadRequest); var funcInfo = functionLoader.GetFunctionInfo(functionId); Assert.Equal(scriptPathExpected, funcInfo.ScriptPath); Assert.Equal(entryPointExpected, funcInfo.EntryPoint); }
internal void SendFunctionLoadRequest(FunctionRegistrationContext context) { FunctionMetadata metadata = context.Metadata; // associate the invocation input buffer with the function _functionInputBuffers[context.Metadata.FunctionId] = context.InputBuffer; // send a load request for the registered function FunctionLoadRequest request = new FunctionLoadRequest() { FunctionId = metadata.FunctionId, Metadata = new RpcFunctionMetadata() { Name = metadata.Name, Directory = metadata.FunctionDirectory ?? string.Empty, EntryPoint = metadata.EntryPoint ?? string.Empty, ScriptFile = metadata.ScriptFile ?? string.Empty } }; if (_managedDependencyOptions?.Value != null) { _workerChannelLogger?.LogInformation($"Adding dependency download request to {_workerConfig.Language} language worker"); request.ManagedDependencyEnabled = _managedDependencyOptions.Value.Enabled; } foreach (var binding in metadata.Bindings) { BindingInfo bindingInfo = binding.ToBindingInfo(); request.Metadata.Bindings.Add(binding.Name, bindingInfo); } SendStreamingMessage(new StreamingMessage { FunctionLoadRequest = request }); }
public PowerShellManagerTests() { _functionDirectory = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "TestScripts", "PowerShell"); _rpcFunctionMetadata = new RpcFunctionMetadata() { Name = "TestFuncApp", Directory = _functionDirectory, Bindings = { { TestInputBindingName, new BindingInfo { Direction = BindingInfo.Types.Direction.In, Type = "httpTrigger" } }, { TestOutputBindingName, new BindingInfo { Direction = BindingInfo.Types.Direction.Out, Type = "http" } } } }; _functionLoadRequest = new FunctionLoadRequest { FunctionId = "FunctionId", Metadata = _rpcFunctionMetadata }; FunctionLoader.SetupWellKnownPaths(_functionLoadRequest); _testLogger = new ConsoleLogger(); _testManager = new PowerShellManager(_testLogger); _testManager.PerformWorkerLevelInitialization(); _testInputData = new List <ParameterBinding> { new ParameterBinding { Name = TestInputBindingName, Data = new TypedData { String = TestStringData } } }; }
public GrpcFunctionDefinition(FunctionLoadRequest loadRequest, IMethodInfoLocator methodInfoLocator) { EntryPoint = loadRequest.Metadata.EntryPoint; Name = loadRequest.Metadata.Name; PathToAssembly = Path.GetFullPath(loadRequest.Metadata.ScriptFile); Id = loadRequest.FunctionId; var grpcBindingsGroup = loadRequest.Metadata.Bindings.GroupBy(kv => kv.Value.Direction); var grpcInputBindings = grpcBindingsGroup.Where(kv => kv.Key == BindingInfo.Types.Direction.In).FirstOrDefault(); var grpcOutputBindings = grpcBindingsGroup.Where(kv => kv.Key != BindingInfo.Types.Direction.In).FirstOrDefault(); var infoToMetadataLambda = new Func <KeyValuePair <string, BindingInfo>, BindingMetadata>(kv => new GrpcBindingMetadata(kv.Value)); InputBindings = grpcInputBindings?.ToImmutableDictionary(kv => kv.Key, infoToMetadataLambda) ?? ImmutableDictionary <string, BindingMetadata> .Empty; OutputBindings = grpcOutputBindings?.ToImmutableDictionary(kv => kv.Key, infoToMetadataLambda) ?? ImmutableDictionary <string, BindingMetadata> .Empty; Parameters = methodInfoLocator.GetMethod(PathToAssembly, EntryPoint) .GetParameters() .Where(p => p.Name != null) .Select(p => new FunctionParameter(p.Name !, p.ParameterType)) .ToImmutableArray(); }