public DotNetFunctionDescriptorProvider(ScriptHost host, ScriptHostConfiguration config, ICompilationServiceFactory compilationServiceFactory) : base(host, config) { _assemblyLoader = new FunctionAssemblyLoader(config.RootScriptPath); _compilationServiceFactory = compilationServiceFactory; }
protected EndToEndTestFixture(string rootPath, string testId) { _settingsManager = ScriptSettingsManager.Instance; FixtureId = testId; string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); QueueClient = storageAccount.CreateCloudQueueClient(); BlobClient = storageAccount.CreateCloudBlobClient(); TableClient = storageAccount.CreateCloudTableClient(); CreateTestStorageEntities(); TraceWriter = new TestTraceWriter(TraceLevel.Verbose); ApiHubTestHelper.SetDefaultConnectionFactory(); ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = rootPath, TraceWriter = TraceWriter, FileLoggingMode = FileLoggingMode.Always }; RequestConfiguration = new HttpConfiguration(); RequestConfiguration.Formatters.Add(new PlaintextMediaTypeFormatter()); // Reset the timer logs first, since one of the tests will // be checking them TestHelpers.ClearFunctionLogs("TimerTrigger"); Host = ScriptHost.Create(_settingsManager, config); Host.Start(); }
public TableBinding(ScriptHostConfiguration config, TableBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { if (string.IsNullOrEmpty(metadata.TableName)) { throw new ArgumentException("The table name cannot be null or empty."); } TableName = metadata.TableName; PartitionKey = metadata.PartitionKey; if (!string.IsNullOrEmpty(PartitionKey)) { _partitionKeyBindingTemplate = BindingTemplate.FromString(PartitionKey); } RowKey = metadata.RowKey; if (!string.IsNullOrEmpty(RowKey)) { _rowKeyBindingTemplate = BindingTemplate.FromString(RowKey); } _tableQuery = new TableQuery { TakeCount = metadata.Take ?? 50, FilterString = metadata.Filter }; }
protected FunctionBinding(ScriptHostConfiguration config, string name, string type, FileAccess fileAccess, bool isTrigger) { _config = config; Name = name; Type = type; FileAccess = fileAccess; IsTrigger = isTrigger; }
public static NodeScriptHost Create(ScriptHostConfiguration scriptConfig) { JobHostConfiguration config = new JobHostConfiguration(); NodeScriptHost scriptHost = new NodeScriptHost(config, scriptConfig); scriptHost.Initialize(); return scriptHost; }
public NotificationHubBinding(ScriptHostConfiguration config, NotificationHubBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { TagExpression = metadata.TagExpression; ConnectionString = metadata.Connection; HubName = metadata.HubName; _bindingDirection = metadata.Direction; }
private static TraceWriter CreateTraceWriter(ScriptHostConfiguration scriptConfig, string functionName) { if (scriptConfig.FileLoggingEnabled) { string logFilePath = Path.Combine(scriptConfig.RootLogPath, "Function", functionName); return new FileTraceWriter(logFilePath, TraceLevel.Verbose); } return NullTraceWriter.Instance; }
public BlobBinding(ScriptHostConfiguration config, BlobBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { if (string.IsNullOrEmpty(metadata.Path)) { throw new ArgumentException("The blob path cannot be null or empty."); } Path = metadata.Path; _pathBindingTemplate = BindingTemplate.FromString(Path); }
public EasyTableBinding(ScriptHostConfiguration config, EasyTableBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { TableName = metadata.TableName; Id = metadata.Id; MobileAppUri = metadata.Connection; ApiKey = metadata.ApiKey; _bindingDirection = metadata.Direction; }
public DocumentDBBinding(ScriptHostConfiguration config, DocumentDBBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { DatabaseName = metadata.DatabaseName; CollectionName = metadata.CollectionName; CreateIfNotExists = metadata.CreateIfNotExists; ConnectionString = metadata.Connection; Id = metadata.Id; _bindingDirection = metadata.Direction; }
public async Task Generate_EndToEnd() { // construct our TimerTrigger attribute ([TimerTrigger("00:00:02", RunOnStartup = true)]) Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); ParameterDescriptor parameter = new ParameterDescriptor("timerInfo", typeof(TimerInfo)); ConstructorInfo ctorInfo = typeof(TimerTriggerAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo runOnStartupProperty = typeof(TimerTriggerAttribute).GetProperty("RunOnStartup"); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder( ctorInfo, new object[] { "00:00:02" }, new PropertyInfo[] { runOnStartupProperty }, new object[] { true }); parameter.CustomAttributes.Add(attributeBuilder); parameters.Add(parameter); // create the FunctionDefinition FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor("TimerFunction", invoker, metadata, parameters); Collection<FunctionDescriptor> functions = new Collection<FunctionDescriptor>(); functions.Add(function); // Get the Type Attributes (in this case, a TimeoutAttribute) ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = TimeSpan.FromMinutes(5); Collection<CustomAttributeBuilder> typeAttributes = ScriptHost.CreateTypeAttributes(scriptConfig); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod("TimerFunction"); TimeoutAttribute timeoutAttribute = (TimeoutAttribute)functionType.GetCustomAttributes().Single(); Assert.Equal(TimeSpan.FromMinutes(5), timeoutAttribute.Timeout); Assert.True(timeoutAttribute.ThrowOnTimeout); Assert.True(timeoutAttribute.TimeoutWhileDebugging); ParameterInfo triggerParameter = method.GetParameters()[0]; TimerTriggerAttribute triggerAttribute = triggerParameter.GetCustomAttribute<TimerTriggerAttribute>(); Assert.NotNull(triggerAttribute); // start the JobHost which will start running the timer function JobHostConfiguration config = new JobHostConfiguration() { TypeLocator = new TypeLocator(functionType) }; config.UseTimers(); JobHost host = new JobHost(config); await host.StartAsync(); await Task.Delay(3000); await host.StopAsync(); // verify our custom invoker was called Assert.True(invoker.InvokeCount >= 2); }
public void ApplyConfiguration_TopLevel() { JObject config = new JObject(); config["id"] = ID; ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); ScriptHost.ApplyConfiguration(config, scriptConfig); Assert.Equal(ID, scriptConfig.HostConfig.HostId); }
public QueueBinding(ScriptHostConfiguration config, QueueBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { if (string.IsNullOrEmpty(metadata.QueueName)) { throw new ArgumentException("The queue name cannot be null or empty."); } QueueName = metadata.QueueName; _queueNameBindingTemplate = BindingTemplate.FromString(QueueName); }
public FunctionDescriptorProviderTests() { string rootPath = Path.Combine(Environment.CurrentDirectory, @"TestScripts\Node"); ScriptHostConfiguration config = new ScriptHostConfiguration { RootScriptPath = rootPath }; _settingsManager = ScriptSettingsManager.Instance; _host = ScriptHost.Create(_settingsManager, config); _provider = new TestDescriptorProvider(_host, config); }
private static ScriptHostInfo GetScriptHostInfo() { string rootPath = Path.Combine(Environment.CurrentDirectory, @"TestScripts\PowerShell"); ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration() { RootScriptPath = rootPath }; var host = ScriptHost.Create(scriptConfig); return(new ScriptHostInfo(host, scriptConfig, rootPath)); }
protected void InitializeConfig(ScriptHostConfiguration config) { config.OnConfigurationApplied = c => { // turn this off as it makes validation tough config.HostConfig.Aggregator.IsEnabled = false; // Overwrite the generated function whitelist to only include two functions. c.Functions = new[] { "Scenarios", "HttpTrigger-Scenarios" }; }; }
public void ApplyConfiguration_TimeoutDefaultsNull_IfNotDynamic() { JObject config = new JObject(); config["id"] = ID; ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); ScriptHost.ApplyConfiguration(config, scriptConfig); Assert.Null(scriptConfig.FunctionTimeout); }
public WebScriptHostManager(ScriptHostConfiguration config, ISecretManagerFactory secretManagerFactory, IScriptEventManager eventManager, ScriptSettingsManager settingsManager, WebHostSettings webHostSettings, IWebJobsRouter router, IScriptHostFactory scriptHostFactory, ILoggerFactoryBuilder loggerFactoryBuilder) : this(config, secretManagerFactory, eventManager, settingsManager, webHostSettings, router, scriptHostFactory, new DefaultSecretsRepositoryFactory(), loggerFactoryBuilder) { }
public EventHubBinding(ScriptHostConfiguration config, EventHubBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { if (string.IsNullOrEmpty(metadata.Path)) { throw new ArgumentException("The event hub path cannot be null or empty."); } EventHubName = metadata.Path; _eventHubNameBindingTemplate = BindingTemplate.FromString(EventHubName); }
private static TraceWriter CreateTraceWriter(ScriptHostConfiguration scriptConfig, string functionName) { if (scriptConfig.FileLoggingEnabled) { TraceLevel functionTraceLevel = scriptConfig.HostConfig.Tracing.ConsoleLevel; string logFilePath = Path.Combine(scriptConfig.RootLogPath, "Function", functionName); return(new FileTraceWriter(logFilePath, functionTraceLevel)); } return(NullTraceWriter.Instance); }
public void GetDefaultHostId_AzureHost_ReturnsExpectedResult(string input, string expected) { var config = new ScriptHostConfiguration(); var scriptSettingsManagerMock = new Mock <ScriptSettingsManager>(MockBehavior.Strict); scriptSettingsManagerMock.SetupGet(p => p.AzureWebsiteUniqueSlotName).Returns(() => input); string hostId = ScriptHost.GetDefaultHostId(scriptSettingsManagerMock.Object, config); Assert.Equal(expected, hostId); }
private RunDependencies CreateDependencies(TraceLevel traceLevel = TraceLevel.Info) { var dependencies = new RunDependencies(); var traceWriter = new TestTraceWriter(System.Diagnostics.TraceLevel.Verbose); var scriptHostConfiguration = new ScriptHostConfiguration { HostConfig = new JobHostConfiguration(), TraceWriter = traceWriter, FileLoggingMode = FileLoggingMode.Always, FileWatchingEnabled = true }; scriptHostConfiguration.HostConfig.Tracing.ConsoleLevel = System.Diagnostics.TraceLevel.Verbose; var host = new Mock <ScriptHost>(scriptHostConfiguration); host.SetupGet(h => h.IsPrimary).Returns(true); var entrypointResolver = new Mock <IFunctionEntryPointResolver>(); var compilation = new Mock <ICompilation>(); compilation.Setup(c => c.GetDiagnostics()) .Returns(ImmutableArray <Diagnostic> .Empty); var compilationService = new Mock <ICompilationService>(); compilationService.Setup(s => s.SupportedFileTypes) .Returns(() => new[] { ".csx" }); compilationService.Setup(s => s.GetFunctionCompilation(It.IsAny <FunctionMetadata>())) .Returns(compilation.Object); var compilationServiceFactory = new Mock <ICompilationServiceFactory>(); compilationServiceFactory.Setup(f => f.CreateService(ScriptType.CSharp, It.IsAny <IFunctionMetadataResolver>())) .Returns(compilationService.Object); var traceWriterFactory = new Mock <ITraceWriterFactory>(); traceWriterFactory.Setup(f => f.Create()) .Returns(traceWriter); return(new RunDependencies { Host = host, EntrypointResolver = entrypointResolver, Compilation = compilation, CompilationService = compilationService, CompilationServiceFactory = compilationServiceFactory, TraceWriterFactory = traceWriterFactory, TraceWriter = traceWriter }); }
private static ScriptHostInfo GetScriptHostInfo() { var environment = new Mock <IScriptHostEnvironment>(); string rootPath = Path.Combine(Environment.CurrentDirectory, @"TestScripts\PowerShell"); ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration() { RootScriptPath = rootPath }; var host = ScriptHost.Create(environment.Object, scriptConfig, SettingsManager); return(new ScriptHostInfo(host, scriptConfig, rootPath)); }
public async Task EmptyHost_StartsSuccessfully() { await _fixture.InitializationTask; string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString()); Directory.CreateDirectory(functionTestDir); // important for the repro that these directories no not exist string logDir = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString()); string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString()); JObject hostConfig = new JObject { { "id", "123456" } }; File.WriteAllText(Path.Combine(functionTestDir, ScriptConstants.HostMetadataFileName), hostConfig.ToString()); ScriptHostConfiguration config = new ScriptHostConfiguration { RootScriptPath = functionTestDir, RootLogPath = logDir, FileLoggingMode = FileLoggingMode.Always }; string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); ISecretsRepository repository = new BlobStorageSecretsRepository(secretsDir, connectionString, "EmptyHost_StartsSuccessfully"); ISecretManager secretManager = new SecretManager(_settingsManager, repository, null); WebHostSettings webHostSettings = new WebHostSettings(); webHostSettings.SecretsPath = _secretsDirectory.Path; var mockEventManager = new Mock <IScriptEventManager>(); IWebJobsRouter router = _fixture.CreateRouter(); ScriptHostManager hostManager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), mockEventManager.Object, _settingsManager, webHostSettings, router, NullLoggerFactory.Instance); Task runTask = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => hostManager.State == ScriptHostState.Running, timeout : 10000); hostManager.Stop(); Assert.Equal(ScriptHostState.Default, hostManager.State); // give some time for the logs to be flushed fullly await Task.Delay(FileWriter.LogFlushIntervalMs * 3); string hostLogFilePath = Directory.EnumerateFiles(Path.Combine(logDir, "Host")).Single(); string hostLogs = File.ReadAllText(hostLogFilePath); Assert.Contains("Generating 0 job function(s)", hostLogs); Assert.Contains("No job functions found.", hostLogs); Assert.Contains("Job host started", hostLogs); Assert.Contains("Job host stopped", hostLogs); }
public void ReadFunctionMetadata_Succeeds() { var config = new ScriptHostConfiguration { RootScriptPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\sample") }; var traceWriter = new TestTraceWriter(TraceLevel.Verbose); var functionErrors = new Dictionary <string, Collection <string> >(); var metadata = ScriptHost.ReadFunctionMetadata(config, traceWriter, functionErrors); Assert.Equal(49, metadata.Count); }
public static FunctionBinding CreateTestBinding(JObject json) { ScriptBindingContext context = new ScriptBindingContext(json); WebJobsCoreScriptBindingProvider provider = new WebJobsCoreScriptBindingProvider(new JobHostConfiguration(), new JObject(), null); ScriptBinding scriptBinding = null; provider.TryCreate(context, out scriptBinding); BindingMetadata bindingMetadata = BindingMetadata.Create(json); ScriptHostConfiguration config = new ScriptHostConfiguration(); return(new ExtensionBinding(config, scriptBinding, bindingMetadata)); }
public ServiceBusBinding(ScriptHostConfiguration config, ServiceBusBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { string queueOrTopicName = metadata.QueueName ?? metadata.TopicName; if (string.IsNullOrEmpty(queueOrTopicName)) { throw new ArgumentException("A valid queue or topic name must be specified."); } QueueOrTopicName = queueOrTopicName; _queueOrTopicNameBindingTemplate = BindingTemplate.FromString(QueueOrTopicName); }
// TODO: FACAVAL (WEBHOOKS) //public WebHookReceiverManager GetWebHookReceiverManager(WebHostSettings settings) //{ // if (_activeReceiverManager != null) // { // return _activeReceiverManager; // } // lock (_syncLock) // { // EnsureInitialized(settings); // return _activeReceiverManager ?? _standbyReceiverManager; // } //} internal void EnsureInitialized(WebHostSettings settings) { if (!WebScriptHostManager.InStandbyMode) { // standby mode can only change from true to false // when standby mode changes, we reset all instances if (_activeHostManager == null) { _settingsManager.Reset(); _activeScriptHostConfig = CreateScriptHostConfiguration(settings); _activeHostManager = new WebScriptHostManager(_activeScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, settings, _router, _loggerFactoryBuilder); //_activeReceiverManager = new WebHookReceiverManager(_activeHostManager.SecretManager); InitializeFileSystem(); if (_standbyHostManager != null) { // we're starting the one and only one // standby mode specialization _activeScriptHostConfig.TraceWriter.Info(Resources.HostSpecializationTrace); // After specialization, we need to ensure that custom timezone // settings configured by the user (WEBSITE_TIME_ZONE) are honored. // DateTime caches timezone information, so we need to clear the cache. TimeZoneInfo.ClearCachedData(); } if (_standbyHostManager != null) { _standbyHostManager.Stop(); _standbyHostManager.Dispose(); } //_standbyReceiverManager?.Dispose(); _standbyScriptHostConfig = null; _standbyHostManager = null; //_standbyReceiverManager = null; } } else { if (_standbyHostManager == null) { var standbySettings = CreateStandbySettings(settings); _standbyScriptHostConfig = CreateScriptHostConfiguration(standbySettings, true); _standbyHostManager = new WebScriptHostManager(_standbyScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, standbySettings, _router, _loggerFactoryBuilder); // _standbyReceiverManager = new WebHookReceiverManager(_standbyHostManager.SecretManager); InitializeFileSystem(); StandbyManager.Initialize(_standbyScriptHostConfig); } } }
public DocumentDBBinding(ScriptHostConfiguration config, DocumentDBBindingMetadata metadata, FileAccess access) : base(config, metadata, access) { DatabaseName = metadata.DatabaseName; CollectionName = metadata.CollectionName; CreateIfNotExists = metadata.CreateIfNotExists; ConnectionString = metadata.Connection; Id = metadata.Id; PartitionKey = metadata.PartitionKey; CollectionThroughput = metadata.CollectionThroughput; _bindingDirection = metadata.Direction; }
public static Uri FilePathToVfsUri(string filePath, string baseUrl, ScriptHostConfiguration config, bool isDirectory = false) { var home = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ScriptSettingsManager.Instance.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath) ?? config.RootScriptPath : Path.DirectorySeparatorChar.ToString(); filePath = filePath .Substring(home.Length) .Trim('\\', '/') .Replace("\\", "/"); return(new Uri($"{baseUrl}/admin/vfs/{filePath}{(isDirectory ? "/" : string.Empty)}")); }
public void Generate_WithMultipleOutParameters() { string functionName = "FunctionWithOuts"; Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); parameters.Add(new ParameterDescriptor("param2", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); parameters.Add(new ParameterDescriptor("param3", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // Make sure we don't generate a TimeoutAttribute if FunctionTimeout is null. ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = null; Collection <CustomAttributeBuilder> typeAttributes = ScriptHost.CreateTypeAttributes(scriptConfig); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); IEnumerable <Attribute> attributes = functionType.GetCustomAttributes(); Assert.Empty(attributes); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that out parameters were correctly generated Assert.True(functionParams[1].IsOut); Assert.True(functionParams[2].IsOut); // Verify that the method is invocable method.Invoke(null, new object[] { "test", null, null }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); }
internal static void Initialize(ContainerBuilder builder, WebHostSettings settings) { ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration() { RootScriptPath = settings.ScriptPath, RootLogPath = settings.LogPath, FileLoggingEnabled = true }; // If running on Azure Web App, derive the host ID from the site name string hostId = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); if (!String.IsNullOrEmpty(hostId)) { // Truncate to the max host name length if needed const int MaximumHostIdLength = 32; if (hostId.Length > MaximumHostIdLength) { hostId = hostId.Substring(0, MaximumHostIdLength); } // Trim any trailing - as they can cause problems with queue names hostId = hostId.TrimEnd('-'); scriptHostConfig.HostConfig.HostId = hostId.ToLowerInvariant(); } SecretManager secretManager = new SecretManager(settings.SecretsPath); // Make sure that host secrets get created on startup if they don't exist secretManager.GetHostSecrets(); builder.RegisterInstance <SecretManager>(secretManager); WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig, secretManager); builder.RegisterInstance <WebScriptHostManager>(scriptHostManager); WebHookReceiverManager webHookReceiverManager = new WebHookReceiverManager(secretManager); builder.RegisterInstance <WebHookReceiverManager>(webHookReceiverManager); if (!settings.IsSelfHost) { HostingEnvironment.QueueBackgroundWorkItem((ct) => scriptHostManager.RunAndBlock(ct)); } else { Task.Run(() => scriptHostManager.RunAndBlock()); } }
static void Main(string[] args) { var config = new ScriptHostConfiguration() { // RootLogPath = Environment.CurrentDirectory, RootScriptPath = "C:\\Users\\tsushi\\source\\repos\\MyAzureFunctions\\sample\\MyFunc", IsSelfHost = true, FileLoggingMode = FileLoggingMode.Always, RootLogPath = Environment.CurrentDirectory }; var scriptHostManager = new ScriptHostManager(config); scriptHostManager.RunAndBlock(); }
public FileLoggerTests() { _config = new ScriptHostConfiguration { FileLoggingMode = FileLoggingMode.Always }; _functionLogPath = Path.Combine(_config.RootLogPath, "Function", _functionName); if (Directory.Exists(_functionLogPath)) { Directory.Delete(_functionLogPath, true); } }
public void AddLoggerProviders(ILoggerFactory factory, ScriptHostConfiguration scriptConfig, ScriptSettingsManager settingsManager) { // Automatically register App Insights if the key is present if (!string.IsNullOrEmpty(settingsManager?.ApplicationInsightsInstrumentationKey)) { ITelemetryClientFactory clientFactory = scriptConfig.HostConfig.GetService <ITelemetryClientFactory>() ?? new ConsoleTelemetryClientFactory(settingsManager.ApplicationInsightsInstrumentationKey, scriptConfig.LogFilter.Filter); scriptConfig.HostConfig.LoggerFactory.AddApplicationInsights(clientFactory); } // TODO: Get trace level, add console logger scriptConfig.HostConfig.LoggerFactory.AddColoredConsole((cat, lvl) => cat.StartsWith("Worker."), false); }
protected ScriptHostEndToEndTestFixture(string rootPath, string testId, ProxyClientExecutor proxyClient = null, bool startHost = true) { _settingsManager = ScriptSettingsManager.Instance; FixtureId = testId; string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); QueueClient = storageAccount.CreateCloudQueueClient(); BlobClient = storageAccount.CreateCloudBlobClient(); TableClient = storageAccount.CreateCloudTableClient(); CreateTestStorageEntities().Wait(); // ApiHubTestHelper.SetDefaultConnectionFactory(); ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = rootPath, FileLoggingMode = FileLoggingMode.Always }; RequestConfiguration = new HttpConfiguration(); EventManager = new ScriptEventManager(); ScriptHostEnvironmentMock = new Mock <IScriptHostEnvironment>(); LoggerProvider = new TestLoggerProvider(); ILoggerProviderFactory loggerProviderFactory = new TestLoggerProviderFactory(LoggerProvider); // Reset the timer logs first, since one of the tests will // be checking them TestHelpers.ClearFunctionLogs("TimerTrigger"); TestHelpers.ClearFunctionLogs("ListenerStartupException"); InitializeConfig(config); Func <string, FunctionDescriptor> funcLookup = (name) => this.Host.GetFunctionOrNull(name); var fastLogger = new FunctionInstanceLogger(funcLookup, new MetricsLogger()); config.HostConfig.AddService <IAsyncCollector <FunctionInstanceLogEntry> >(fastLogger); _settingsManager.Reset(); Host = new ScriptHost(ScriptHostEnvironmentMock.Object, EventManager, config, _settingsManager, proxyClient: proxyClient, loggerProviderFactory: loggerProviderFactory); Host.Initialize(); if (startHost) { Host.HostStarted += (s, e) => _hostStartedEvent.Set(); Host.Start(); _hostStartedEvent.Wait(TimeSpan.FromSeconds(30)); } }
protected EndToEndTestFixture(string rootPath) { CreateTestStorageEntities(); TraceWriter = new TestTraceWriter(TraceLevel.Verbose); ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = rootPath, TraceWriter = TraceWriter }; Host = ScriptHost.Create(config); Host.Start(); }
private static ScriptHostConfiguration CreateScriptHostConfiguration(WebHostSettings settings) { InitializeFileSystem(settings.ScriptPath); var scriptHostConfig = new ScriptHostConfiguration() { RootScriptPath = settings.ScriptPath, RootLogPath = settings.LogPath, FileLoggingMode = FileLoggingMode.DebugOnly, TraceWriter = settings.TraceWriter }; return(scriptHostConfig); }
public static string VfsUriToFilePath(Uri uri, ScriptHostConfiguration config, bool isDirectory = false) { var home = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ScriptSettingsManager.Instance.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath) ?? config.RootScriptPath : Path.DirectorySeparatorChar.ToString(); var filePath = uri.AbsolutePath.Split("/admin/vfs").LastOrDefault(); filePath = string.IsNullOrEmpty(filePath) ? home : Path.Combine(home, filePath.TrimStart('/')); return(filePath.Replace('/', Path.DirectorySeparatorChar)); }
public ScriptHost Create(ScriptHostConfiguration config) { if (Throw) { throw new Exception("Kaboom!"); } var mockMetricsLogger = new Mock <IMetricsLogger>(MockBehavior.Strict); config.HostConfig.AddService <IMetricsLogger>(mockMetricsLogger.Object); mockMetricsLogger.Setup(p => p.LogEvent(It.IsAny <MetricEvent>())); return(ScriptHost.Create(config)); }
public async Task EmptyHost_StartsSuccessfully() { string functionDir = Path.Combine(TestHelpers.FunctionsTestDirectory, "Functions", Guid.NewGuid().ToString()); Directory.CreateDirectory(functionDir); // important for the repro that this directory does not exist string logDir = Path.Combine(TestHelpers.FunctionsTestDirectory, "Logs", Guid.NewGuid().ToString()); JObject hostConfig = new JObject { { "id", "123456" } }; File.WriteAllText(Path.Combine(functionDir, ScriptConstants.HostMetadataFileName), hostConfig.ToString()); ScriptHostConfiguration config = new ScriptHostConfiguration { RootScriptPath = functionDir, RootLogPath = logDir, FileLoggingMode = FileLoggingMode.Always }; var eventManagerMock = new Mock <IScriptEventManager>(); ScriptHostManager hostManager = new ScriptHostManager(config, eventManagerMock.Object); // start the host and wait for it to be running Task runTask = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => hostManager.State == ScriptHostState.Running, timeout : 10000); // exercise restart hostManager.RestartHost(); Assert.Equal(ScriptHostState.Default, hostManager.State); await TestHelpers.Await(() => hostManager.State == ScriptHostState.Running, timeout : 10000); // stop the host fully hostManager.Stop(); Assert.Equal(ScriptHostState.Default, hostManager.State); await Task.Delay(FileTraceWriter.LogFlushIntervalMs); string hostLogFilePath = Directory.EnumerateFiles(Path.Combine(logDir, "Host")).Single(); string hostLogs = File.ReadAllText(hostLogFilePath); Assert.Contains("Generating 0 job function(s)", hostLogs); Assert.Contains("No job functions found.", hostLogs); Assert.Contains("Job host started", hostLogs); Assert.Contains("Job host stopped", hostLogs); }
public LanguageWorkerChannel( ScriptHostConfiguration scriptConfig, IScriptEventManager eventManager, IWorkerProcessFactory processFactory, IProcessRegistry processRegistry, IObservable <FunctionRegistrationContext> functionRegistrations, WorkerConfig workerConfig, Uri serverUri, ILoggerFactory loggerFactory) { _workerId = Guid.NewGuid().ToString(); _scriptConfig = scriptConfig; _eventManager = eventManager; _processFactory = processFactory; _processRegistry = processRegistry; _functionRegistrations = functionRegistrations; _workerConfig = workerConfig; _serverUri = serverUri; _logger = loggerFactory.CreateLogger($"Worker.{workerConfig.Language}.{_workerId}"); _inboundWorkerEvents = _eventManager.OfType <InboundEvent>() .Where(msg => msg.WorkerId == _workerId); _eventSubscriptions.Add(_inboundWorkerEvents .Where(msg => msg.MessageType == MsgType.RpcLog) .Subscribe(Log)); if (scriptConfig.LogFilter.Filter("Worker", LogLevel.Trace)) { _eventSubscriptions.Add(_eventManager.OfType <RpcEvent>() .Where(msg => msg.WorkerId == _workerId) .Subscribe(msg => { var jsonMsg = JsonConvert.SerializeObject(msg, _verboseSerializerSettings); // TODO: change to trace when ILogger & TraceWriter merge (issues with file trace writer) _logger.LogInformation(jsonMsg); })); } _eventSubscriptions.Add(_eventManager.OfType <FileEvent>() .Where(msg => Path.GetExtension(msg.FileChangeArguments.FullPath) == Config.Extension) .Throttle(TimeSpan.FromMilliseconds(300)) // debounce .Subscribe(msg => _eventManager.Publish(new HostRestartEvent()))); StartWorker(); }
public AdminControllerTests() { _settingsManager = ScriptSettingsManager.Instance; testFunctions = new Collection<FunctionDescriptor>(); var config = new ScriptHostConfiguration(); hostMock = new Mock<ScriptHost>(MockBehavior.Strict, new object[] { config }); hostMock.Setup(p => p.Functions).Returns(testFunctions); WebHostSettings settings = new WebHostSettings(); managerMock = new Mock<WebScriptHostManager>(MockBehavior.Strict, new object[] { config, new TestSecretManagerFactory(), _settingsManager, settings }); managerMock.SetupGet(p => p.Instance).Returns(hostMock.Object); testController = new AdminController(managerMock.Object); }
public ApiHubBinding(ScriptHostConfiguration config, ApiHubBindingMetadata apiHubBindingMetadata, FileAccess access) : base(config, apiHubBindingMetadata, access) { if (apiHubBindingMetadata == null) { throw new ArgumentNullException("apiHubBindingMetadata"); } if (string.IsNullOrEmpty(apiHubBindingMetadata.Path)) { throw new ArgumentException("The ApiHub path cannot be null or empty."); } Key = apiHubBindingMetadata.Key; Path = apiHubBindingMetadata.Path; _pathBindingTemplate = BindingTemplate.FromString(Path); }
public void Generate_WithMultipleOutParameters() { string functionName = "FunctionWithOuts"; Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); parameters.Add(new ParameterDescriptor("param2", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); parameters.Add(new ParameterDescriptor("param3", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection<FunctionDescriptor> functions = new Collection<FunctionDescriptor>(); functions.Add(function); // Make sure we don't generate a TimeoutAttribute if FunctionTimeout is null. ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = null; Collection<CustomAttributeBuilder> typeAttributes = ScriptHost.CreateTypeAttributes(scriptConfig); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); IEnumerable<Attribute> attributes = functionType.GetCustomAttributes(); Assert.Empty(attributes); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that out parameters were correctly generated Assert.True(functionParams[1].IsOut); Assert.True(functionParams[2].IsOut); // Verify that the method is invocable method.Invoke(null, new object[] { "test", null, null }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); }
public TableBinding(ScriptHostConfiguration config, string name, string tableName, string partitionKey, string rowKey, FileAccess fileAccess, TableQuery tableQuery = null) : base(config, name, "queue", fileAccess, false) { TableName = tableName; PartitionKey = partitionKey; RowKey = rowKey; _partitionKeyBindingTemplate = BindingTemplate.FromString(PartitionKey); if (!string.IsNullOrEmpty(RowKey)) { _rowKeyBindingTemplate = BindingTemplate.FromString(RowKey); } _tableQuery = tableQuery; if (_tableQuery == null) { _tableQuery = new TableQuery { TakeCount = 50 }; } }
public WebScriptHostManager(ScriptHostConfiguration config, ISecretManagerFactory secretManagerFactory, ScriptSettingsManager settingsManager, WebHostSettings webHostSettings, IScriptHostFactory scriptHostFactory = null) : base(config, settingsManager, scriptHostFactory) { _config = config; _metricsLogger = new WebHostMetricsLogger(); _exceptionHandler = new WebScriptHostExceptionHandler(this); _webHostSettings = webHostSettings; var systemEventGenerator = config.HostConfig.GetService<IEventGenerator>() ?? new EventGenerator(); var systemTraceWriter = new SystemTraceWriter(systemEventGenerator, settingsManager, TraceLevel.Verbose); if (config.TraceWriter != null) { config.TraceWriter = new CompositeTraceWriter(new TraceWriter[] { config.TraceWriter, systemTraceWriter }); } else { config.TraceWriter = systemTraceWriter; } _secretManager = secretManagerFactory.Create(settingsManager, config.TraceWriter, webHostSettings.SecretsPath); }
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; } }
public static void Main(string[] args) { if (args == null) { throw new ArgumentNullException("args"); } string rootPath = Environment.CurrentDirectory; if (args.Length > 0) { rootPath = (string)args[0]; } ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = rootPath }; ScriptHostManager scriptHostManager = new ScriptHostManager(config); scriptHostManager.RunAndBlock(); }
protected FunctionDescriptorProvider(ScriptHost host, ScriptHostConfiguration config) { Host = host; Config = config; }
internal static Collection<FunctionBinding> GetBindings(ScriptHostConfiguration config, IEnumerable<BindingMetadata> bindingMetadatas, FileAccess fileAccess) { Collection<FunctionBinding> bindings = new Collection<FunctionBinding>(); if (bindings != null) { foreach (var bindingMetadata in bindingMetadatas) { BindingType type = bindingMetadata.Type; string name = bindingMetadata.Name; switch (type) { case BindingType.Blob: case BindingType.BlobTrigger: BlobBindingMetadata blobBindingMetadata = (BlobBindingMetadata)bindingMetadata; bindings.Add(new BlobBinding(config, name, blobBindingMetadata.Path, fileAccess, bindingMetadata.IsTrigger)); break; case BindingType.Queue: case BindingType.QueueTrigger: QueueBindingMetadata queueBindingMetadata = (QueueBindingMetadata)bindingMetadata; if (!queueBindingMetadata.IsTrigger && fileAccess != FileAccess.Write) { throw new InvalidOperationException("Queue binding can only be used for output."); } bindings.Add(new QueueBinding(config, name, queueBindingMetadata.QueueName, fileAccess, bindingMetadata.IsTrigger)); break; case BindingType.ServiceBus: case BindingType.ServiceBusTrigger: ServiceBusBindingMetadata serviceBusBindingMetadata = (ServiceBusBindingMetadata)bindingMetadata; if (!serviceBusBindingMetadata.IsTrigger && fileAccess != FileAccess.Write) { throw new InvalidOperationException("ServiceBus binding can only be used for output."); } string queueOrTopicName = serviceBusBindingMetadata.QueueName ?? serviceBusBindingMetadata.TopicName; bindings.Add(new ServiceBusBinding(config, name, queueOrTopicName, fileAccess, bindingMetadata.IsTrigger)); break; case BindingType.Table: TableBindingMetadata tableBindingMetadata = (TableBindingMetadata)bindingMetadata; TableQuery tableQuery = new TableQuery { TakeCount = tableBindingMetadata.Take, FilterString = tableBindingMetadata.Filter }; bindings.Add(new TableBinding(config, name, tableBindingMetadata.TableName, tableBindingMetadata.PartitionKey, tableBindingMetadata.RowKey, fileAccess, tableQuery)); break; case BindingType.Http: HttpBindingMetadata httpBindingMetadata = (HttpBindingMetadata)bindingMetadata; if (fileAccess != FileAccess.Write) { throw new InvalidOperationException("Http binding can only be used for output."); } name = name ?? "res"; bindings.Add(new HttpBinding(config, name, FileAccess.Write, bindingMetadata.IsTrigger)); break; } } } return bindings; }
public WebScriptHostManager(ScriptHostConfiguration config, ISecretManagerFactory secretManagerFactory, ScriptSettingsManager settingsManager, WebHostSettings webHostSettings) : this(config, secretManagerFactory, settingsManager, webHostSettings, new ScriptHostFactory()) { }
protected override void OnInitializeConfig(ScriptHostConfiguration config) { base.OnInitializeConfig(config); // Note: this method can be called many times for the same ScriptHostConfiguration // so no changes should be made to the configuration itself. It is safe to modify // ScriptHostConfiguration.Host config though, since the inner JobHostConfiguration // is created anew on each restart. // Add our WebHost specific services var hostConfig = config.HostConfig; hostConfig.AddService<IMetricsLogger>(_metricsLogger); // Add our exception handler hostConfig.AddService<IWebJobsExceptionHandler>(_exceptionHandler); // Register the new "FastLogger" for Dashboard support var dashboardString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Dashboard); if (dashboardString != null) { // hostId may be missing in local test scenarios. var hostId = config.HostConfig.HostId ?? "default"; var fastLogger = new FastLogger(hostId, dashboardString); hostConfig.AddService<IAsyncCollector<FunctionInstanceLogEntry>>(fastLogger); } hostConfig.DashboardConnectionString = null; // disable slow logging }
public static void WarmUp(WebHostSettings settings) { var traceWriter = new FileTraceWriter(Path.Combine(settings.LogPath, "Host"), TraceLevel.Info); ScriptHost host = null; try { traceWriter.Info("Warm up started"); string rootPath = settings.ScriptPath; if (Directory.Exists(rootPath)) { Directory.Delete(rootPath, true); } Directory.CreateDirectory(rootPath); string content = ReadResourceString("Functions.host.json"); File.WriteAllText(Path.Combine(rootPath, "host.json"), content); // read in the C# function string functionPath = Path.Combine(rootPath, "Test-CSharp"); Directory.CreateDirectory(functionPath); content = ReadResourceString("Functions.Test_CSharp.function.json"); File.WriteAllText(Path.Combine(functionPath, "function.json"), content); content = ReadResourceString("Functions.Test_CSharp.run.csx"); File.WriteAllText(Path.Combine(functionPath, "run.csx"), content); // read in the F# function functionPath = Path.Combine(rootPath, "Test-FSharp"); Directory.CreateDirectory(functionPath); content = ReadResourceString("Functions.Test_FSharp.function.json"); File.WriteAllText(Path.Combine(functionPath, "function.json"), content); content = ReadResourceString("Functions.Test_FSharp.run.fsx"); File.WriteAllText(Path.Combine(functionPath, "run.fsx"), content); traceWriter.Info("Warm up functions deployed"); ScriptHostConfiguration config = new ScriptHostConfiguration { RootScriptPath = rootPath, FileLoggingMode = FileLoggingMode.Never, RootLogPath = settings.LogPath, TraceWriter = traceWriter, FileWatchingEnabled = false }; config.HostConfig.StorageConnectionString = null; config.HostConfig.DashboardConnectionString = null; host = ScriptHost.Create(ScriptSettingsManager.Instance, config); traceWriter.Info(string.Format("Starting Host (Id={0})", host.ScriptConfig.HostConfig.HostId)); host.Start(); var arguments = new Dictionary<string, object> { { "input", "{}" } }; host.CallAsync("Test-CSharp", arguments).Wait(); host.CallAsync("Test-FSharp", arguments).Wait(); host.Stop(); traceWriter.Info("Warm up succeeded"); } catch (Exception ex) { traceWriter.Error(string.Format("Warm up failed: {0}", ex)); } finally { host?.Dispose(); traceWriter.Dispose(); } }
public HttpBinding(ScriptHostConfiguration config, string name, FileAccess fileAccess, bool isTrigger) : base(config, name, "http", fileAccess, isTrigger) { }
public ScriptFunctionDescriptorProvider(ScriptHost host, ScriptHostConfiguration config) : base(host, config) { }
public CSharpFunctionDescriptionProvider(ScriptHost host, ScriptHostConfiguration config) : base(host, config) { _assemblyLoader = new FunctionAssemblyLoader(config.RootScriptPath); }