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 }; }
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); }
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); }
public void PublishWorkerMetadataResponse(string workerId, string functionId, IEnumerable <FunctionMetadata> functionMetadata, bool successful, bool useDefaultMetadataIndexing = false, bool overallStatus = true) { StatusResult statusResult = new StatusResult(); if (successful) { statusResult.Status = StatusResult.Types.Status.Success; } else { statusResult.Status = StatusResult.Types.Status.Failure; } FunctionMetadataResponse overallResponse = new FunctionMetadataResponse(); overallResponse.UseDefaultMetadataIndexing = useDefaultMetadataIndexing; if (functionMetadata != null) { foreach (FunctionMetadata response in functionMetadata) { RpcFunctionMetadata indexingResponse = new RpcFunctionMetadata() { Name = response.Name, Language = response.Language, Status = statusResult, FunctionId = functionId }; overallResponse.FunctionMetadataResults.Add(indexingResponse); } } overallResponse.Result = new StatusResult() { Status = overallStatus == true ? StatusResult.Types.Status.Success : StatusResult.Types.Status.Failure }; StreamingMessage responseMessage = new StreamingMessage() { FunctionMetadataResponse = overallResponse }; _eventManager.Publish(new InboundGrpcEvent(_workerId, responseMessage)); }
internal AzFunctionInfo(RpcFunctionMetadata metadata) { FunctionName = metadata.Name; Directory = metadata.Directory; EntryPoint = metadata.EntryPoint; ScriptPath = metadata.ScriptFile; AllBindings = new MapField <string, BindingInfo>(); OutputBindings = new MapField <string, BindingInfo>(); foreach (var binding in metadata.Bindings) { string bindingName = binding.Key; BindingInfo bindingInfo = binding.Value; AllBindings.Add(bindingName, bindingInfo); // PowerShell doesn't support the 'InOut' type binding if (bindingInfo.Direction == BindingInfo.Types.Direction.In) { switch (bindingInfo.Type) { case OrchestrationTrigger: Type = AzFunctionType.OrchestrationFunction; break; case ActivityTrigger: Type = AzFunctionType.ActivityFunction; break; default: Type = AzFunctionType.RegularFunction; break; } continue; } if (bindingInfo.Direction == BindingInfo.Types.Direction.Out) { OutputBindings.Add(bindingName, bindingInfo); } } }
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); }
public FunctionInfo(RpcFunctionMetadata metadata) { FunctionName = metadata.Name; Directory = metadata.Directory; EntryPoint = metadata.EntryPoint; ScriptPath = metadata.ScriptFile; AllBindings = new MapField <string, BindingInfo>(); OutputBindings = new MapField <string, BindingInfo>(); foreach (var binding in metadata.Bindings) { AllBindings.Add(binding.Key, binding.Value); // PowerShell doesn't support the 'InOut' type binding if (binding.Value.Direction == BindingInfo.Types.Direction.Out) { OutputBindings.Add(binding.Key, binding.Value); } } }
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); }
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 } } }; }
/// <summary> /// Construct an object of AzFunctionInfo from the 'RpcFunctionMetadata'. /// Necessary validations are done on the metadata and script. /// </summary> internal AzFunctionInfo(RpcFunctionMetadata metadata) { FuncName = metadata.Name; FuncDirectory = metadata.Directory; EntryPoint = metadata.EntryPoint; ScriptPath = metadata.ScriptFile; // Support 'entryPoint' only if 'scriptFile' is a .psm1 file; // Support .psm1 'scriptFile' only if 'entryPoint' is specified. bool isScriptFilePsm1 = ScriptPath.EndsWith(".psm1", StringComparison.OrdinalIgnoreCase); bool entryPointNotDefined = string.IsNullOrEmpty(EntryPoint); if (entryPointNotDefined) { if (isScriptFilePsm1) { throw new ArgumentException(PowerShellWorkerStrings.RequireEntryPointForScriptModule); } } else if (!isScriptFilePsm1) { throw new ArgumentException(PowerShellWorkerStrings.InvalidEntryPointForScriptFile); } // Get the parameter names of the script or function. var psScriptParams = GetParameters(ScriptPath, EntryPoint, out ScriptBlockAst scriptAst); FuncParameters = new ReadOnlyDictionary <string, PSScriptParamInfo>(psScriptParams); var parametersCopy = new Dictionary <string, PSScriptParamInfo>(psScriptParams, StringComparer.OrdinalIgnoreCase); HasTriggerMetadataParam = parametersCopy.Remove(TriggerMetadata); HasTraceContextParam = parametersCopy.Remove(TraceContext); var allBindings = new Dictionary <string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase); var inputBindings = new Dictionary <string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase); var outputBindings = new Dictionary <string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase); var inputsMissingFromParams = new List <string>(); foreach (var binding in metadata.Bindings) { string bindingName = binding.Key; var bindingInfo = new ReadOnlyBindingInfo(binding.Value); allBindings.Add(bindingName, bindingInfo); if (bindingInfo.Direction == BindingInfo.Types.Direction.In) { Type = GetAzFunctionType(bindingInfo); inputBindings.Add(bindingName, bindingInfo); // If the input binding name is in the set, we remove it; // otherwise, the binding name is missing from the params. if (!parametersCopy.Remove(bindingName)) { inputsMissingFromParams.Add(bindingName); } } else if (bindingInfo.Direction == BindingInfo.Types.Direction.Out) { if (bindingInfo.Type == OrchestrationClient) { OrchestrationClientBindingName = bindingName; } outputBindings.Add(bindingName, bindingInfo); } else { // PowerShell doesn't support the 'InOut' type binding throw new InvalidOperationException(string.Format(PowerShellWorkerStrings.InOutBindingNotSupported, bindingName)); } } if (inputsMissingFromParams.Count != 0 || parametersCopy.Count != 0) { StringBuilder stringBuilder = new StringBuilder(); foreach (string inputBindingName in inputsMissingFromParams) { stringBuilder.AppendFormat(PowerShellWorkerStrings.MissingParameter, inputBindingName).AppendLine(); } foreach (string param in parametersCopy.Keys) { stringBuilder.AppendFormat(PowerShellWorkerStrings.UnknownParameter, param).AppendLine(); } string errorMsg = stringBuilder.ToString(); throw new InvalidOperationException(errorMsg); } if (entryPointNotDefined && scriptAst.ScriptRequirements == null) { // If the function script is a '.ps1' file that doesn't have '#requires' defined, // then we get the script block and will deploy it as a PowerShell function in the // global scope of each Runspace, so as to avoid hitting the disk every invocation. FuncScriptBlock = scriptAst.GetScriptBlock(); DeployedPSFuncName = $"_{FuncName}_"; } AllBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(allBindings); InputBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(inputBindings); OutputBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(outputBindings); }
/// <summary> /// Construct an object of AzFunctionInfo from the 'RpcFunctionMetadata'. /// Necessary validations are done on the metadata and script. /// </summary> internal AzFunctionInfo(RpcFunctionMetadata metadata) { FuncName = metadata.Name; FuncDirectory = metadata.Directory; EntryPoint = metadata.EntryPoint; ScriptPath = metadata.ScriptFile; // Support 'entryPoint' only if 'scriptFile' is a .psm1 file; // Support .psm1 'scriptFile' only if 'entryPoint' is specified. bool isScriptFilePsm1 = ScriptPath.EndsWith(".psm1", StringComparison.OrdinalIgnoreCase); if (string.IsNullOrEmpty(EntryPoint)) { if (isScriptFilePsm1) { throw new ArgumentException(PowerShellWorkerStrings.RequireEntryPointForScriptModule); } } else if (!isScriptFilePsm1) { throw new ArgumentException(PowerShellWorkerStrings.InvalidEntryPointForScriptFile); } // Get the parameter names of the script or function. var psScriptParams = GetParameters(ScriptPath, EntryPoint); FuncParameters = new ReadOnlyDictionary <string, PSScriptParamInfo>(psScriptParams); var parametersCopy = new Dictionary <string, PSScriptParamInfo>(psScriptParams, StringComparer.OrdinalIgnoreCase); HasTriggerMetadataParam = parametersCopy.Remove(TriggerMetadata); var allBindings = new Dictionary <string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase); var inputBindings = new Dictionary <string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase); var outputBindings = new Dictionary <string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase); var inputsMissingFromParams = new List <string>(); foreach (var binding in metadata.Bindings) { string bindingName = binding.Key; var bindingInfo = new ReadOnlyBindingInfo(binding.Value); allBindings.Add(bindingName, bindingInfo); if (bindingInfo.Direction == BindingInfo.Types.Direction.In) { Type = GetAzFunctionType(bindingInfo); inputBindings.Add(bindingName, bindingInfo); // If the input binding name is in the set, we remove it; // otherwise, the binding name is missing from the params. if (!parametersCopy.Remove(bindingName)) { inputsMissingFromParams.Add(bindingName); } } else if (bindingInfo.Direction == BindingInfo.Types.Direction.Out) { outputBindings.Add(bindingName, bindingInfo); } else { // PowerShell doesn't support the 'InOut' type binding throw new InvalidOperationException(string.Format(PowerShellWorkerStrings.InOutBindingNotSupported, bindingName)); } } if (inputsMissingFromParams.Count != 0 || parametersCopy.Count != 0) { StringBuilder stringBuilder = new StringBuilder(); foreach (string inputBindingName in inputsMissingFromParams) { stringBuilder.AppendFormat(PowerShellWorkerStrings.MissingParameter, inputBindingName).AppendLine(); } foreach (string param in parametersCopy.Keys) { stringBuilder.AppendFormat(PowerShellWorkerStrings.UnknownParameter, param).AppendLine(); } string errorMsg = stringBuilder.ToString(); throw new InvalidOperationException(errorMsg); } AllBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(allBindings); InputBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(inputBindings); OutputBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(outputBindings); }
/// <summary> /// Construct an object of AzFunctionInfo from the 'RpcFunctionMetadata'. /// Necessary validations are done on the metadata and script. /// </summary> internal AzFunctionInfo(RpcFunctionMetadata metadata) { FuncName = metadata.Name; FuncDirectory = metadata.Directory; EntryPoint = metadata.EntryPoint; ScriptPath = metadata.ScriptFile; // Support 'entryPoint' only if 'scriptFile' is a .psm1 file; // Support .psm1 'scriptFile' only if 'entryPoint' is specified. bool isScriptFilePsm1 = ScriptPath.EndsWith(".psm1", StringComparison.OrdinalIgnoreCase); if (string.IsNullOrEmpty(EntryPoint)) { if (isScriptFilePsm1) { throw new ArgumentException($"The 'entryPoint' property needs to be specified when 'scriptFile' points to a PowerShell module script file (.psm1)."); } } else if (!isScriptFilePsm1) { throw new ArgumentException($"The 'entryPoint' property is supported only if 'scriptFile' points to a PowerShell module script file (.psm1)."); } // Get the parameter names of the script or function. FuncParameters = GetParameters(ScriptPath, EntryPoint); var parametersCopy = new HashSet <string>(FuncParameters, StringComparer.OrdinalIgnoreCase); parametersCopy.Remove(TriggerMetadata); var allBindings = new Dictionary <string, ReadOnlyBindingInfo>(); var inputBindings = new Dictionary <string, ReadOnlyBindingInfo>(); var outputBindings = new Dictionary <string, ReadOnlyBindingInfo>(); var inputsMissingFromParams = new List <string>(); foreach (var binding in metadata.Bindings) { string bindingName = binding.Key; var bindingInfo = new ReadOnlyBindingInfo(binding.Value); allBindings.Add(bindingName, bindingInfo); if (bindingInfo.Direction == BindingInfo.Types.Direction.In) { Type = GetAzFunctionType(bindingInfo); inputBindings.Add(bindingName, bindingInfo); // If the input binding name is in the set, we remove it; // otherwise, the binding name is missing from the params. if (!parametersCopy.Remove(bindingName)) { inputsMissingFromParams.Add(bindingName); } } else if (bindingInfo.Direction == BindingInfo.Types.Direction.Out) { outputBindings.Add(bindingName, bindingInfo); } else { // PowerShell doesn't support the 'InOut' type binding throw new InvalidOperationException($"The binding '{bindingName}' is declared with 'InOut' direction, which is not supported by PowerShell functions."); } } if (inputsMissingFromParams.Count != 0 || parametersCopy.Count != 0) { StringBuilder stringBuilder = new StringBuilder(); foreach (string inputBindingName in inputsMissingFromParams) { stringBuilder.AppendLine($"No parameter defined in the script or function for the input binding '{inputBindingName}'."); } foreach (string param in parametersCopy) { stringBuilder.AppendLine($"No input binding defined for the parameter '{param}' that is declared in the script or function."); } string errorMsg = stringBuilder.ToString(); throw new InvalidOperationException(errorMsg); } AllBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(allBindings); InputBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(inputBindings); OutputBindings = new ReadOnlyDictionary <string, ReadOnlyBindingInfo>(outputBindings); }