Example #1
0
        public async Task<FunctionEnvelope> CreateOrUpdateAsync(string name, FunctionEnvelope functionEnvelope, Action setConfigChanged)
        {
            var functionDir = Path.Combine(_environment.FunctionsPath, name);

            // Make sure the function folder exists
            FileSystemHelpers.EnsureDirectory(functionDir);

            string newConfig = null;
            string configPath = Path.Combine(functionDir, Constants.FunctionsConfigFile);
            string dataFilePath = GetFunctionTestDataFilePath(name);

            // If files are included, write them out
            if (functionEnvelope?.Files != null)
            {
                // If the config is passed in the file collection, save it and don't process it as a file
                if (functionEnvelope.Files.TryGetValue(Constants.FunctionsConfigFile, out newConfig))
                {
                    functionEnvelope.Files.Remove(Constants.FunctionsConfigFile);
                }

                // Delete all existing files in the directory. This will also delete current function.json, but it gets recreated below
                FileSystemHelpers.DeleteDirectoryContentsSafe(functionDir);

                await Task.WhenAll(functionEnvelope.Files.Select(e => FileSystemHelpers.WriteAllTextToFileAsync(Path.Combine(functionDir, e.Key), e.Value)));
            }

            // Get the config (if it was not already passed in as a file)
            if (newConfig == null && functionEnvelope?.Config != null)
            {
                newConfig = JsonConvert.SerializeObject(functionEnvelope?.Config, Formatting.Indented);
            }

            // Get the current config, if any
            string currentConfig = null;
            if (FileSystemHelpers.FileExists(configPath))
            {
                currentConfig = await FileSystemHelpers.ReadAllTextFromFileAsync(configPath);
            }

            // Save the file and set changed flag is it has changed. This helps optimize the syncTriggers call
            if (newConfig != currentConfig)
            {
                await FileSystemHelpers.WriteAllTextToFileAsync(configPath, newConfig);
                setConfigChanged();
            }

            if (functionEnvelope.TestData != null)
            {
                await FileSystemHelpers.WriteAllTextToFileAsync(dataFilePath, functionEnvelope.TestData);
            }

            return await GetFunctionConfigAsync(name);
        }
Example #2
0
        // Compute the site ID, for both the top level function API case and the regular nested case
        private FunctionEnvelope AddFunctionAppIdToEnvelope(FunctionEnvelope function)
        {
            Uri referrer = Request.Headers.Referrer;
            if (referrer == null) return function;

            string armId = referrer.AbsolutePath;

            const string msWeb = "Microsoft.Web";
            const string functionResource = msWeb + "/functions";
            const string sitesResource = msWeb + "/sites";

            // Input: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/functions/{funcname}
            int index = armId.IndexOf(functionResource, StringComparison.OrdinalIgnoreCase);
            if (index > 0)
            {
                // Produce: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{sitename}
                function.FunctionAppId = $"{armId.Substring(0, index)}{sitesResource}/{Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")}";
                return function;
            }

            // Input: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{sitename}/functions/{funcname}
            index = armId.IndexOf(sitesResource, StringComparison.OrdinalIgnoreCase);
            if (index > 0)
            {
                // Produce: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{sitename}
                index = armId.IndexOf("/", index + sitesResource.Length + 1, StringComparison.OrdinalIgnoreCase);
                function.FunctionAppId = armId.Substring(0, index);
                return function;
            }

            return function;
        }
Example #3
0
        public async Task<FunctionEnvelope> CreateOrUpdateAsync(string name, FunctionEnvelope functionEnvelope)
        {
            var functionDir = Path.Combine(_environment.FunctionsPath, name);

            // Make sure the function folder exists
            FileSystemHelpers.EnsureDirectory(functionDir);

            // If files are included, write them out
            if (functionEnvelope?.Files != null)
            {
                // Delete all existing files in the directory. This will also delete current function.json, but it gets recreated below
                FileSystemHelpers.DeleteDirectoryContentsSafe(functionDir);

                await Task.WhenAll(functionEnvelope.Files.Select(e => FileSystemHelpers.WriteAllTextToFileAsync(Path.Combine(functionDir, e.Key), e.Value)));
            }

            // Write out the config file if it's in the manifest
            if (functionEnvelope?.Config != null)
            {
                await FileSystemHelpers.WriteAllTextToFileAsync(Path.Combine(functionDir, Constants.FunctionsConfigFile), JsonConvert.SerializeObject(functionEnvelope?.Config, Formatting.Indented));
            }

            return await GetFunctionConfigAsync(name);
        }
Example #4
0
        public void GetTriggers_ReturnsExpectedResults()
        {
            FunctionEnvelope excludedFunction = new FunctionEnvelope
            {
                Name = "TestExcludedFunction",
                Config = new JObject
                {
                    { "excluded", true }
                }
            };
            FunctionEnvelope disabledFunction = new FunctionEnvelope
            {
                Name = "TestDisabledFunction",
                Config = new JObject
                {
                    { "disabled", true }
                }
            };

            FunctionEnvelope invalidFunction = new FunctionEnvelope
            {
                Name = "TestInvalidFunction",
                Config = new JObject
                {
                    { "bindings", "invalid" }
                }
            };

            var queueTriggerFunction = new FunctionEnvelope
            {
                Name = "TestQueueFunction",
                Config = new JObject
                {
                    { "bindings", new JArray
                        {
                            new JObject
                            {
                                { "type", "queueTrigger" },
                                { "direction", "in" },
                                { "queueName", "test" }
                            },
                            new JObject
                            {
                                { "type", "blob" },
                                { "direction", "out" },
                                { "path", "test" }
                            }
                        }
                    }
                }
            };

            List<FunctionEnvelope> functions = new List<FunctionEnvelope>
            {
                excludedFunction,
                disabledFunction,
                invalidFunction,
                queueTriggerFunction
            };

            var triggers = FunctionManager.GetTriggers(functions, NullTracer.Instance);

            Assert.Equal(1, triggers.Count);

            var trigger = triggers[0];
            Assert.Equal(queueTriggerFunction.Name, (string)trigger["functionName"]);
            Assert.Equal(queueTriggerFunction.Config["bindings"][0], trigger);
        }