static void Main() { CreateDemoData(); JobHost host = new JobHost(); host.RunAndBlock(); }
public void TestSdkMarkerIsWrittenWhenInAzureWebSites() { // Arrange string tempDir = Path.GetTempPath(); const string filename = "WebJobsSdk.marker"; var path = Path.Combine(tempDir, filename); File.Delete(path); IServiceProvider configuration = CreateConfiguration(); using (JobHost host = new JobHost(configuration)) { try { Environment.SetEnvironmentVariable(WebSitesKnownKeyNames.JobDataPath, tempDir); // Act host.Start(); // Assert Assert.True(File.Exists(path), "SDK marker file should have been written"); } finally { Environment.SetEnvironmentVariable(WebSitesKnownKeyNames.JobDataPath, null); File.Delete(path); } } }
public static void Run(string connectionString) { CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); CreateTestQueues(queueClient); try { CloudQueue firstQueue = queueClient.GetQueueReference(_nameResolver.ResolveInString(FunctionChainingPerfTest.FirstQueueName)); firstQueue.AddMessage(new CloudQueueMessage("Test")); _startBlock = MeasurementBlock.BeginNew(0, HostStartMetric); JobHostConfiguration hostConfig = new JobHostConfiguration(connectionString); hostConfig.NameResolver = _nameResolver; hostConfig.TypeLocator = new FakeTypeLocator(typeof(FunctionChainingPerfTest)); JobHost host = new JobHost(hostConfig); _tokenSource = new CancellationTokenSource(); Task stopTask = null; _tokenSource.Token.Register(() => stopTask = host.StopAsync()); host.RunAndBlock(); stopTask.GetAwaiter().GetResult(); } finally { DeleteTestQueues(queueClient); } }
public void ThrowsArgumentNullExceptionIfWorkIsNull() { var host = new JobHost(); var exception = Assert.Throws<ArgumentNullException>(() => host.DoWork(null)); Assert.Equal("work", exception.ParamName); }
public WebHookDispatcher(WebHooksConfiguration webHooksConfig, JobHost host, JobHostConfiguration config, TraceWriter trace) { _functions = new ConcurrentDictionary<string, ITriggeredFunctionExecutor>(); _trace = trace; _port = webHooksConfig.Port; _types = config.TypeLocator.GetTypes().ToArray(); _host = host; }
public void EnsuresNoWorkIsDone() { var host = new JobHost(); var task = new Task(() => { throw new InvalidOperationException("Hey, this is supposed to be shut down!"); }); host.Stop(true); host.DoWork(task); }
static void Main() { CreateDemoData(); JobHost host = new JobHost(); host.Call(typeof(Program).GetMethod("ManualTrigger")); host.RunAndBlock(); }
public void StartAsync_WhenNotStarted_DoesNotThrow() { // Arrange using (JobHost host = new JobHost(CreateConfiguration())) { // Act & Assert host.StartAsync().GetAwaiter().GetResult(); } }
public static void Main() { // See the AzureJobsData and AzureJobsRuntime in the app.config var host = new JobHost(); var m = typeof(Program).GetMethod("AggregateRss"); host.Call(m); Console.WriteLine(" aggregated to:"); Console.WriteLine("https://{0}.blob.core.windows.net/blog/output.rss.xml", host.UserAccountName); }
public async Task<JobHostContext> CreateAndLogHostStartedAsync(JobHost host, CancellationToken shutdownToken, CancellationToken cancellationToken) { IHostIdProvider hostIdProvider = null; if (_config.HostId != null) { hostIdProvider = new FixedHostIdProvider(_config.HostId); } return await CreateAndLogHostStartedAsync(host, _storageAccountProvider, _config.Queues, _config.TypeLocator, _config.JobActivator, _config.NameResolver, _consoleProvider, _config, shutdownToken, cancellationToken, hostIdProvider); }
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 BlobGetsProcessedOnlyOnce_SingleHost() { TextWriter hold = Console.Out; StringWriter consoleOutput = new StringWriter(); Console.SetOut(consoleOutput); CloudBlockBlob blob = _testContainer.GetBlockBlobReference(BlobName); blob.UploadText("0"); int timeToProcess; // Process the blob first using (_blobProcessedEvent = new ManualResetEvent(initialState: false)) using (JobHost host = new JobHost(_hostConfiguration)) { DateTime startTime = DateTime.Now; host.Start(); Assert.True(_blobProcessedEvent.WaitOne(TimeSpan.FromSeconds(60))); timeToProcess = (int)(DateTime.Now - startTime).TotalMilliseconds; host.Stop(); Console.SetOut(hold); string[] consoleOutputLines = consoleOutput.ToString().Trim().Split(new string[] { Environment.NewLine }, StringSplitOptions.None); string[] expectedOutputLines = new string[] { "Found the following functions:", "Microsoft.Azure.WebJobs.Host.EndToEndTests.BlobTriggerTests.SingleBlobTrigger", "Job host started", string.Format("Executing: 'BlobTriggerTests.SingleBlobTrigger' - Reason: 'New blob detected: {0}/{1}'", blob.Container.Name, blob.Name), "Executed: 'BlobTriggerTests.SingleBlobTrigger' (Succeeded)", "Job host stopped", }; Assert.True(consoleOutputLines.SequenceEqual(expectedOutputLines)); } // Then start again and make sure the blob doesn't get reprocessed // wait twice the amount of time required to process first before // deciding that it doesn't get reprocessed using (_blobProcessedEvent = new ManualResetEvent(initialState: false)) using (JobHost host = new JobHost(_hostConfiguration)) { host.Start(); bool blobReprocessed = _blobProcessedEvent.WaitOne(2 * timeToProcess); host.Stop(); Assert.False(blobReprocessed); } }
public void DoesNotCallStartIfWorkIsAlreadyScheduledOrCompleted() { var tcs = new TaskCompletionSource<object>(); tcs.SetResult(null); var task = tcs.Task; var host = new JobHost(); Assert.DoesNotThrow(() => host.DoWork(task)); }
public void StartAsync_WhenStarted_Throws() { // Arrange using (JobHost host = new JobHost(CreateConfiguration())) { host.Start(); // Act & Assert ExceptionAssert.ThrowsInvalidOperation(() => host.StartAsync(), "Start has already been called."); } }
static void Main() { CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureJobsData"].ConnectionString); CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = queueClient.GetQueueReference("inputtext"); queue.CreateIfNotExist(); queue.AddMessage(new CloudQueueMessage("Hello World!")); // The connection string is read from App.config JobHost host = new JobHost(); host.RunAndBlock(); }
public async Task<JobHostContext> CreateAndLogHostStartedAsync(JobHost host, CancellationToken shutdownToken, CancellationToken cancellationToken) { IHostIdProvider hostIdProvider = null; if (_config.HostId != null) { hostIdProvider = new FixedHostIdProvider(_config.HostId); } var fastLogger = _config.GetService<IAsyncCollector<FunctionInstanceLogEntry>>(); return await CreateAndLogHostStartedAsync(host, _storageAccountProvider, _config.Queues, _config.TypeLocator, _config.JobActivator, _config.NameResolver, _consoleProvider, _config, shutdownToken, cancellationToken, hostIdProvider, fastLogger: fastLogger); }
/// <summary> /// There is a function that takes > 10 minutes and listens to a queue. /// </summary> /// <remarks>Ignored because it takes a long time. Can be enabled on demand</remarks> // Uncomment the Fact attribute to run //[Fact(Timeout = 20 * 60 * 1000)] public void QueueMessageLeaseRenew() { _messageFoundAgain = false; _queue.AddMessage(new CloudQueueMessage("Test")); _tokenSource = new CancellationTokenSource(); JobHost host = new JobHost(_config); _tokenSource.Token.Register(host.Stop); host.RunAndBlock(); Assert.False(_messageFoundAgain); }
public void CanBindExecutionContext() { JobHostConfiguration config = new JobHostConfiguration { TypeLocator = new ExplicitTypeLocator(typeof(CoreTestJobs)) }; config.UseCore(); JobHost host = new JobHost(config); host.Call(typeof(CoreTestJobs).GetMethod("ExecutionContext")); ExecutionContext result = CoreTestJobs.Context; Assert.NotNull(result); Assert.NotEqual(Guid.Empty, result.InvocationId); }
public Task<JobHostContext> CreateAndLogHostStartedAsync(JobHost host, CancellationToken shutdownToken, CancellationToken cancellationToken) { INameResolver nameResolver = new RandomNameResolver(); JobHostConfiguration config = new JobHostConfiguration { NameResolver = nameResolver, TypeLocator = TypeLocator }; return JobHostContextFactory.CreateAndLogHostStartedAsync( host, StorageAccountProvider, QueueConfiguration, TypeLocator, DefaultJobActivator.Instance, nameResolver, ConsoleProvider, new JobHostConfiguration(), shutdownToken, cancellationToken, HostIdProvider, FunctionExecutor, FunctionIndexProvider, BindingProvider, HostInstanceLoggerProvider, FunctionInstanceLoggerProvider, FunctionOutputLoggerProvider, BackgroundExceptionDispatcher); }
public Task<JobHostContext> CreateAndLogHostStartedAsync(JobHost host, CancellationToken shutdownToken, CancellationToken cancellationToken) { ITypeLocator typeLocator = new DefaultTypeLocator(new StringWriter(), new DefaultExtensionRegistry()); INameResolver nameResolver = new RandomNameResolver(); JobHostConfiguration config = new JobHostConfiguration { NameResolver = nameResolver, TypeLocator = typeLocator }; return JobHostContextFactory.CreateAndLogHostStartedAsync( host, StorageAccountProvider, Queues, typeLocator, DefaultJobActivator.Instance, nameResolver, new NullConsoleProvider(), new JobHostConfiguration(), shutdownToken, cancellationToken, functionIndexProvider: FunctionIndexProvider, singletonManager: SingletonManager); }
public Task<JobHostContext> CreateAndLogHostStartedAsync(JobHost host, CancellationToken shutdownToken, CancellationToken cancellationToken) { ITypeLocator typeLocator = new DefaultTypeLocator(new StringWriter(), new DefaultExtensionRegistry()); INameResolver nameResolver = new RandomNameResolver(); JobHostConfiguration config = new JobHostConfiguration { NameResolver = nameResolver, TypeLocator = typeLocator }; return JobHostContextFactory.CreateAndLogHostStartedAsync( host, StorageAccountProvider, config.Queues, typeLocator, DefaultJobActivator.Instance, nameResolver, new NullConsoleProvider(), new JobHostConfiguration(), shutdownToken, cancellationToken, new FixedHostIdProvider(Guid.NewGuid().ToString("N")), null, new EmptyFunctionIndexProvider(), null, new NullHostInstanceLoggerProvider(), new NullFunctionInstanceLoggerProvider(), new NullFunctionOutputLoggerProvider(), null, SingletonManager); }
static void Main(string[] args) { CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); FileSystemWatcher watcher = new FileSystemWatcher(@"C:\temp"); watcher.Created += OnFileCreated; host = new JobHost(); // Run the host on a background thread so we can invoke from dashboard host.RunOnBackgroundThread(cancelTokenSource.Token); // Enable the file watcher events and wait watcher.EnableRaisingEvents = true; while (!cancelTokenSource.IsCancellationRequested) { Thread.Sleep(2000); } }
static void Main(string[] args) { CloudStorageAccount storageAccount; if (CloudStorageAccount.TryParse( ConfigurationManager.ConnectionStrings[STORAGE_CONN_STR_KEY_NAME].ConnectionString, out storageAccount)) { // Create the queue we're using to trigger on if it doesn't already exist. CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); CloudQueue queue = queueClient.GetQueueReference(PICTURE_LOADER_QUEUE_NAME.ToLower()); queue.CreateIfNotExists(); } else { Console.WriteLine("Unable to initialize CloudStorageAccount."); } JobHost jobHost = new JobHost(); jobHost.RunAndBlock(); }
static void Main(string[] args) { using (var listener = new ObservableEventListener()) { listener.LogToConsole(new ConsoleFormatter()); listener.EnableEvents(EngineEventSource.Log, EventLevel.Verbose, Keywords.All); listener.EnableEvents(TableStorageEventSource.Log, EventLevel.Verbose, Keywords.All); var eventContext = new TableStorageJobEventContext( CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccount"))); var host = new JobHost(eventContext); host.Add(new LogCleanupJob()); host.Add(new SendNewsletterJob()); host.Add(new LongRunningJob()); host.Start(); Console.WriteLine("Waiting..."); Console.ReadLine(); } }
public void BlobGetsProcessedOnlyOnce_MultipleHosts() { _testContainer .GetBlockBlobReference(BlobName) .UploadText("10"); using (_blobProcessedEvent = new ManualResetEvent(initialState: false)) using (JobHost host1 = new JobHost(_hostConfiguration)) using (JobHost host2 = new JobHost(_hostConfiguration)) { host1.Start(); host2.Start(); Assert.True(_blobProcessedEvent.WaitOne(TimeSpan.FromSeconds(60))); host1.Stop(); host2.Stop(); } Assert.Equal(1, _timesProcessed); }
static int Main(string[] args) { var options = new Options(); if (CommandLine.Parser.Default.ParseArguments(args, options)) { if (0 == String.Compare(options.JobType, "azure", StringComparison.CurrentCultureIgnoreCase)) { Debug.WriteLine("Running in Azure WebJob mode"); var host = new JobHost(); host.Call(typeof(Program).GetMethod("SyncBranchResourceFiles")); } else { Debug.WriteLine("Running in local mode"); SyncBranchResourceFiles(); } return 0; } return 2; }
public void Queue_IfNameIsInvalid_ThrowsDuringIndexing() { IStorageAccount account = CreateFakeStorageAccount(); TaskCompletionSource<object> backgroundTaskSource = new TaskCompletionSource<object>(); IServiceProvider serviceProvider = FunctionalTest.CreateServiceProviderForCallFailure(account, typeof(InvalidQueueNameProgram), backgroundTaskSource); using (JobHost host = new JobHost(serviceProvider)) { // Act & Assert FunctionIndexingException exception = Assert.Throws<FunctionIndexingException>(() => host.Start()); Assert.Equal("Error indexing method 'InvalidQueueNameProgram.Invalid'", exception.Message); Exception innerException = exception.InnerException; Assert.IsType<ArgumentException>(innerException); ArgumentException argumentException = (ArgumentException)innerException; Assert.Equal("name", argumentException.ParamName); string expectedMessage = String.Format(CultureInfo.InvariantCulture, "The dash (-) character may not be the first or last letter - \"-illegalname-\"{0}Parameter " + "name: name", Environment.NewLine); Assert.Equal(expectedMessage, innerException.Message); Assert.Equal(TaskStatus.WaitingForActivation, backgroundTaskSource.Task.Status); } }
public void WaitsForTaskToComplete() { var host = new JobHost(); var workTask = new Task(() => host.DoWork(new Task(() => { // Was getting inconsistent results with Thread.Sleep(100) for (int i = 0; i < 100; i++) { Thread.Sleep(1); } }))); var beforeStop = DateTime.UtcNow; workTask.Start(); while (workTask.Status != TaskStatus.Running) { Thread.Sleep(1); } host.Stop(false); var afterStop = DateTime.UtcNow; // If Stop didn't wait, we'd expect after to be less than 100 ms larger than beforeStop Assert.True((afterStop - beforeStop).TotalMilliseconds >= 100); }
private async Task RunTimerJobTest(Type jobClassType, Func<bool> condition) { TestTraceWriter testTrace = new TestTraceWriter(TraceLevel.Error); ExplicitTypeLocator locator = new ExplicitTypeLocator(jobClassType); JobHostConfiguration config = new JobHostConfiguration { TypeLocator = locator }; config.UseTimers(); config.Tracing.Tracers.Add(testTrace); JobHost host = new JobHost(config); host.Start(); await TestHelpers.Await(() => { return condition(); }); host.Stop(); // ensure there were no errors Assert.Equal(0, testTrace.Events.Count); }
/// <summary> /// defult ctor /// </summary> public AzureJobHost() { _jobHost = new JobHost(); }
public static JobHost GetJobHost( ILoggerFactory loggerFactory, string taskHub, bool enableExtendedSessions, string eventGridKeySettingName = null, INameResolver nameResolver = null, string eventGridTopicEndpoint = null, int?eventGridRetryCount = null, TimeSpan?eventGridRetryInterval = null, int[] eventGridRetryHttpStatus = null, bool logReplayEvents = true, Uri notificationUrl = null) { var config = new JobHostConfiguration { HostId = "durable-task-host" }; config.ConfigureDurableFunctionTypeLocator(typeof(TestOrchestrations), typeof(TestActivities)); var durableTaskExtension = new DurableTaskExtension { HubName = taskHub.Replace("_", "") + (enableExtendedSessions ? "EX" : ""), TraceInputsAndOutputs = true, EventGridKeySettingName = eventGridKeySettingName, EventGridTopicEndpoint = eventGridTopicEndpoint, ExtendedSessionsEnabled = enableExtendedSessions, MaxConcurrentOrchestratorFunctions = 200, MaxConcurrentActivityFunctions = 200, LogReplayEvents = logReplayEvents, NotificationUrl = notificationUrl, }; if (eventGridRetryCount.HasValue) { durableTaskExtension.EventGridPublishRetryCount = eventGridRetryCount.Value; } if (eventGridRetryInterval.HasValue) { durableTaskExtension.EventGridPublishRetryInterval = eventGridRetryInterval.Value; } if (eventGridRetryHttpStatus != null) { durableTaskExtension.EventGridPublishRetryHttpStatus = eventGridRetryHttpStatus; } config.UseDurableTask(durableTaskExtension); // Mock INameResolver for not setting EnvironmentVariables. if (nameResolver != null) { config.AddService <INameResolver>(nameResolver); } // Performance is *significantly* worse when dashboard logging is enabled, at least // when running in the storage emulator. Disabling to keep tests running quickly. config.DashboardConnectionString = null; // Add test logger config.LoggerFactory = loggerFactory; var host = new JobHost(config); return(host); }
public FunctionsV1HostWrapper(JobHost innerHost) { this.innerHost = innerHost ?? throw new ArgumentNullException(nameof(innerHost)); }
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); }
/// <summary> /// Call WebJobEndpoint using the specified parameter as Abp StartupModule /// </summary> /// <typeparam name="TStartupModule">Abp Startup Module</typeparam> public static void Call <TStartupModule>(this JobHost host) where TStartupModule : AbpModule { host.Call(typeof(NServiceBusWebJobEndpoint).GetMethod("Start"), new { startupModule = typeof(TStartupModule) }); }
public FunctionsV2HostWrapper(IHost innerHost) { this.innerHost = innerHost ?? throw new ArgumentNullException(nameof(innerHost)); this.innerWebJobsHost = (JobHost)this.innerHost.Services.GetService <IJobHost>(); }
public TestFixture() { RandomNameResolver nameResolver = new RandomNameResolver(); JobHostConfiguration hostConfiguration = new JobHostConfiguration() { NameResolver = nameResolver, TypeLocator = new FakeTypeLocator(typeof(MultipleStorageAccountsEndToEndTests)), }; Config = hostConfiguration; Account1 = CloudStorageAccount.Parse(hostConfiguration.StorageConnectionString); string secondaryConnectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(Secondary); Account2 = CloudStorageAccount.Parse(secondaryConnectionString); CleanContainers(); CloudBlobClient blobClient1 = Account1.CreateCloudBlobClient(); string inputName = nameResolver.ResolveInString(Input); CloudBlobContainer inputContainer1 = blobClient1.GetContainerReference(inputName); inputContainer1.Create(); string outputName = nameResolver.ResolveWholeString(Output); OutputContainer1 = blobClient1.GetContainerReference(outputName); OutputContainer1.CreateIfNotExists(); CloudBlobClient blobClient2 = Account2.CreateCloudBlobClient(); CloudBlobContainer inputContainer2 = blobClient2.GetContainerReference(inputName); inputContainer2.Create(); OutputContainer2 = blobClient2.GetContainerReference(outputName); OutputContainer2.CreateIfNotExists(); CloudQueueClient queueClient1 = Account1.CreateCloudQueueClient(); CloudQueue inputQueue1 = queueClient1.GetQueueReference(inputName); inputQueue1.CreateIfNotExists(); OutputQueue1 = queueClient1.GetQueueReference(outputName); OutputQueue1.CreateIfNotExists(); CloudQueueClient queueClient2 = Account2.CreateCloudQueueClient(); CloudQueue inputQueue2 = queueClient2.GetQueueReference(inputName); inputQueue2.CreateIfNotExists(); OutputQueue2 = queueClient2.GetQueueReference(outputName); OutputQueue2.CreateIfNotExists(); CloudTableClient tableClient1 = Account1.CreateCloudTableClient(); string outputTableName = nameResolver.ResolveWholeString(OutputTableName); OutputTable1 = tableClient1.GetTableReference(outputTableName); OutputTable2 = Account2.CreateCloudTableClient().GetTableReference(outputTableName); // upload some test blobs to the input containers of both storage accounts CloudBlockBlob blob = inputContainer1.GetBlockBlobReference("blob1"); blob.UploadText(TestData); blob = inputContainer2.GetBlockBlobReference("blob2"); blob.UploadText(TestData); // upload some test queue messages to the input queues of both storage accounts inputQueue1.AddMessage(new CloudQueueMessage(TestData)); inputQueue2.AddMessage(new CloudQueueMessage(TestData)); Host = new JobHost(hostConfiguration); Host.Start(); }
public static async Task <JobHostContext> CreateAndLogHostStartedAsync( JobHost host, IStorageAccountProvider storageAccountProvider, IQueueConfiguration queueConfiguration, JobHostBlobsConfiguration blobsConfiguration, ITypeLocator typeLocator, IJobActivator activator, INameResolver nameResolver, IConsoleProvider consoleProvider, JobHostConfiguration config, CancellationToken shutdownToken, CancellationToken cancellationToken, IWebJobsExceptionHandler exceptionHandler, IHostIdProvider hostIdProvider = null, FunctionExecutor functionExecutor = null, IFunctionIndexProvider functionIndexProvider = null, IBindingProvider bindingProvider = null, IHostInstanceLoggerProvider hostInstanceLoggerProvider = null, IFunctionInstanceLoggerProvider functionInstanceLoggerProvider = null, IFunctionOutputLoggerProvider functionOutputLoggerProvider = null, SingletonManager singletonManager = null, IAsyncCollector <FunctionInstanceLogEntry> fastLogger = null) { if (hostIdProvider == null) { hostIdProvider = new DynamicHostIdProvider(storageAccountProvider, () => functionIndexProvider); } AzureStorageDeploymentValidator.Validate(); var converterManager = config.ConverterManager; IExtensionTypeLocator extensionTypeLocator = new ExtensionTypeLocator(typeLocator); ContextAccessor <IMessageEnqueuedWatcher> messageEnqueuedWatcherAccessor = new ContextAccessor <IMessageEnqueuedWatcher>(); ContextAccessor <IBlobWrittenWatcher> blobWrittenWatcherAccessor = new ContextAccessor <IBlobWrittenWatcher>(); ISharedContextProvider sharedContextProvider = new SharedContextProvider(); // Create a wrapper TraceWriter that delegates to both the user // TraceWriters specified via config (if present), as well as to Console TraceWriter trace = new ConsoleTraceWriter(config.Tracing, consoleProvider.Out); // Register system services with the service container config.AddService <INameResolver>(nameResolver); if (exceptionHandler != null) { exceptionHandler.Initialize(host); } ExtensionConfigContext context = new ExtensionConfigContext { Config = config, Trace = trace }; InvokeExtensionConfigProviders(context); if (singletonManager == null) { singletonManager = new SingletonManager(storageAccountProvider, exceptionHandler, config.Singleton, trace, hostIdProvider, config.NameResolver); } IExtensionRegistry extensions = config.GetExtensions(); ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, blobsConfiguration, exceptionHandler, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, extensions, singletonManager, trace); if (bindingProvider == null) { bindingProvider = DefaultBindingProvider.Create(nameResolver, converterManager, storageAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, extensions); } bool hasFastTableHook = config.GetService <IAsyncCollector <FunctionInstanceLogEntry> >() != null; bool noDashboardStorage = config.DashboardConnectionString == null; if (hasFastTableHook && noDashboardStorage) { var loggerProvider = new FastTableLoggerProvider(trace); hostInstanceLoggerProvider = loggerProvider; functionInstanceLoggerProvider = loggerProvider; functionOutputLoggerProvider = loggerProvider; } else { var loggerProvider = new DefaultLoggerProvider(storageAccountProvider, trace); hostInstanceLoggerProvider = loggerProvider; functionInstanceLoggerProvider = loggerProvider; functionOutputLoggerProvider = loggerProvider; } using (CancellationTokenSource combinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, shutdownToken)) { CancellationToken combinedCancellationToken = combinedCancellationSource.Token; await WriteSiteExtensionManifestAsync(combinedCancellationToken); IStorageAccount dashboardAccount = await storageAccountProvider.GetDashboardAccountAsync(combinedCancellationToken); IHostInstanceLogger hostInstanceLogger = await hostInstanceLoggerProvider.GetAsync(combinedCancellationToken); IFunctionInstanceLogger functionInstanceLogger = await functionInstanceLoggerProvider.GetAsync(combinedCancellationToken); IFunctionOutputLogger functionOutputLogger = await functionOutputLoggerProvider.GetAsync(combinedCancellationToken); if (functionExecutor == null) { functionExecutor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, exceptionHandler, trace, fastLogger); } if (functionIndexProvider == null) { functionIndexProvider = new FunctionIndexProvider(typeLocator, triggerBindingProvider, bindingProvider, activator, functionExecutor, extensions, singletonManager, trace); } IFunctionIndex functions = await functionIndexProvider.GetAsync(combinedCancellationToken); IListenerFactory functionsListenerFactory = new HostListenerFactory(functions.ReadAll(), singletonManager, activator, nameResolver, trace); IFunctionExecutor hostCallExecutor; IListener listener; HostOutputMessage hostOutputMessage; string hostId = await hostIdProvider.GetHostIdAsync(cancellationToken); if (string.Compare(config.HostId, hostId, StringComparison.OrdinalIgnoreCase) != 0) { // if this isn't a static host ID, provide the HostId on the config // so it is accessible config.HostId = hostId; } if (dashboardAccount == null) { hostCallExecutor = new ShutdownFunctionExecutor(shutdownToken, functionExecutor); IListener factoryListener = new ListenerFactoryListener(functionsListenerFactory); IListener shutdownListener = new ShutdownListener(shutdownToken, factoryListener); listener = shutdownListener; hostOutputMessage = new DataOnlyHostOutputMessage(); } else { string sharedQueueName = HostQueueNames.GetHostQueueName(hostId); IStorageQueueClient dashboardQueueClient = dashboardAccount.CreateQueueClient(); IStorageQueue sharedQueue = dashboardQueueClient.GetQueueReference(sharedQueueName); IListenerFactory sharedQueueListenerFactory = new HostMessageListenerFactory(sharedQueue, queueConfiguration, exceptionHandler, trace, functions, functionInstanceLogger, functionExecutor); Guid hostInstanceId = Guid.NewGuid(); string instanceQueueName = HostQueueNames.GetHostQueueName(hostInstanceId.ToString("N")); IStorageQueue instanceQueue = dashboardQueueClient.GetQueueReference(instanceQueueName); IListenerFactory instanceQueueListenerFactory = new HostMessageListenerFactory(instanceQueue, queueConfiguration, exceptionHandler, trace, functions, functionInstanceLogger, functionExecutor); HeartbeatDescriptor heartbeatDescriptor = new HeartbeatDescriptor { SharedContainerName = HostContainerNames.Hosts, SharedDirectoryName = HostDirectoryNames.Heartbeats + "/" + hostId, InstanceBlobName = hostInstanceId.ToString("N"), ExpirationInSeconds = (int)HeartbeatIntervals.ExpirationInterval.TotalSeconds }; IStorageBlockBlob blob = dashboardAccount.CreateBlobClient() .GetContainerReference(heartbeatDescriptor.SharedContainerName) .GetBlockBlobReference(heartbeatDescriptor.SharedDirectoryName + "/" + heartbeatDescriptor.InstanceBlobName); IRecurrentCommand heartbeatCommand = new UpdateHostHeartbeatCommand(new HeartbeatCommand(blob)); IEnumerable <MethodInfo> indexedMethods = functions.ReadAllMethods(); Assembly hostAssembly = GetHostAssembly(indexedMethods); string displayName = hostAssembly != null?hostAssembly.GetName().Name : "Unknown"; hostOutputMessage = new DataOnlyHostOutputMessage { HostInstanceId = hostInstanceId, HostDisplayName = displayName, SharedQueueName = sharedQueueName, InstanceQueueName = instanceQueueName, Heartbeat = heartbeatDescriptor, WebJobRunIdentifier = WebJobRunIdentifier.Current }; hostCallExecutor = CreateHostCallExecutor(instanceQueueListenerFactory, heartbeatCommand, exceptionHandler, shutdownToken, functionExecutor); IListenerFactory hostListenerFactory = new CompositeListenerFactory(functionsListenerFactory, sharedQueueListenerFactory, instanceQueueListenerFactory); listener = CreateHostListener(hostListenerFactory, heartbeatCommand, exceptionHandler, shutdownToken); // Publish this to Azure logging account so that a web dashboard can see it. await LogHostStartedAsync(functions, hostOutputMessage, hostInstanceLogger, combinedCancellationToken); } functionExecutor.HostOutputMessage = hostOutputMessage; IEnumerable <FunctionDescriptor> descriptors = functions.ReadAllDescriptors(); int descriptorsCount = descriptors.Count(); if (config.UsingDevelopmentSettings) { trace.Verbose(string.Format("Development settings applied")); } if (descriptorsCount == 0) { trace.Warning(string.Format("No job functions found. Try making your job classes and methods public. {0}", Constants.ExtensionInitializationMessage), TraceSource.Indexing); } else { StringBuilder functionsTrace = new StringBuilder(); functionsTrace.AppendLine("Found the following functions:"); foreach (FunctionDescriptor descriptor in descriptors) { functionsTrace.AppendLine(descriptor.FullName); } trace.Info(functionsTrace.ToString(), TraceSource.Indexing); } return(new JobHostContext(functions, hostCallExecutor, listener, trace, fastLogger)); } }
public void Initialize(JobHost host) { UnhandledExceptionInfos = new List <ExceptionDispatchInfo>(); TimeoutExceptionInfos = new List <ExceptionDispatchInfo>(); }
public void Test(JobHost <ConfigNullOutParam> host) { host.Call("WriteString"); // Convert was never called }
[InlineData(LogLevel.Warning, 2, 0)] // 2x warning trace per request public async Task QuickPulse_Works_EvenIfFiltered(LogLevel defaultLevel, int tracesPerRequest, int additionalTraces) { using (QuickPulseEventListener qpListener = new QuickPulseEventListener()) using (IHost host = ConfigureHost(defaultLevel)) { ApplicationInsightsTestListener listener = new ApplicationInsightsTestListener(); int functionsCalled = 0; bool keepRunning = true; Task functionTask = null; try { listener.StartListening(); JobHost jobHost = host.GetJobHost(); { await host.StartAsync(); await TestHelpers.Await(() => listener.IsReady); MethodInfo methodInfo = GetType().GetMethod(nameof(TestApplicationInsightsWarning), BindingFlags.Public | BindingFlags.Static); // Start a task to make calls in a loop. functionTask = Task.Run(async() => { while (keepRunning) { await Task.Delay(100); await jobHost.CallAsync(methodInfo); functionsCalled++; } }); // Wait until we're seeing telemetry come through the QuickPulse service double?sum = null; await TestHelpers.Await(() => { // Sum up all req/sec calls that we've received. IEnumerable <QuickPulseMetric> reqPerSec = listener.GetQuickPulseItems() .Select(p => p.Metrics.Where(q => q.Name == @"\ApplicationInsights\Requests/Sec").Single()); sum = reqPerSec.Sum(p => p.Value); // All requests will go to QuickPulse. // Just make sure we have some coming through. Choosing 5 as an arbitrary number. return(sum >= 5); }, timeout : 5000, userMessageCallback : () => { IEnumerable <QuickPulsePayload> items = listener.GetQuickPulseItems().OrderBy(i => i.Timestamp).Take(10); IEnumerable <string> s = items.Select(i => $"[{i.Timestamp.ToString(_dateFormat)}] {i.Metrics.Single(p => p.Name == @"\ApplicationInsights\Requests/Sec")}"); return($"Actual QuickPulse sum: '{sum}'. DefaultLevel: '{defaultLevel}'.{Environment.NewLine}QuickPulse items ({items.Count()}): {string.Join(Environment.NewLine, s)}{Environment.NewLine}QuickPulse Logs:{qpListener.GetLog(20)}{Environment.NewLine}Logs: {host.GetTestLoggerProvider().GetLogString()}"); }); } } finally { keepRunning = false; await functionTask; await host.StopAsync(); listener.StopListening(); listener.Dispose(); } string failureString = string.Join(Environment.NewLine, _channel.Telemetries.Select(t => { string timestamp = $"[{t.Timestamp.ToString(_dateFormat)}] "; switch (t) { case DependencyTelemetry dependency: return(timestamp + $"[Dependency] {dependency.Name}; {dependency.Target}; {dependency.Data}"); case TraceTelemetry trace: return(timestamp + $"[Trace] {trace.Message}"); case RequestTelemetry request: return(timestamp + $"[Request] {request.Name}: {request.Success}"); default: return(timestamp + $"[{t.GetType().Name}]"); } })); int expectedTelemetryItems = additionalTraces + (functionsCalled * tracesPerRequest); // Filter out the odd auto-tracked request that we occassionally see from AppVeyor. // From here: https://github.com/xunit/xunit/blob/9d10262a3694bb099ddd783d735aba2a7aac759d/src/xunit.runner.reporters/AppVeyorClient.cs#L21 var actualTelemetries = _channel.Telemetries .Where(p => !(p is DependencyTelemetry d && d.Name == "POST /api/tests/batch")) .ToArray(); Assert.True(actualTelemetries.Length == expectedTelemetryItems, $"Expected: {expectedTelemetryItems}; Actual: {actualTelemetries.Length}{Environment.NewLine}{failureString}"); } }
/// <summary> /// ctor initialises the Azure Job Host with <see cref="JobHostConfiguration"/> /// </summary> /// <param name="config"><see cref="JobHostConfiguration"/></param> public AzureJobHost(JobHostConfiguration config) { _jobHost = new JobHost(config); }
/// <summary>Calls a job method.</summary> /// <param name="method">The job method to call.</param> /// <param name="arguments">The argument names and values to bind to parameters in the job method. /// In addition to parameter values, these may also include binding data values. </param> protected void Invoke(MethodInfo method, IDictionary <string, object> arguments) { JobHost.Call(method, arguments); }
private void SetupJobHost() { JobHost.Configure(_configurator); }
static void Main(string[] args) { var host = new JobHost(); host.RunAndBlock(); }
// Please set the following connection strings in app.config for this WebJob to run: // AzureWebJobsDashboard and AzureWebJobsStorage static void Main() { // Add telemetry initializers. TelemetryConfiguration.Active.TelemetryInitializers .Add(new CorrelationTelemetryInitializer()); TelemetryConfiguration.Active.TelemetryInitializers .Add(new CloudRoleNameInitializer(ConfigurationManager.AppSettings["ComponentName"])); // Set up logging. using (var loggerFactory = new LoggerFactory()) { var config = new JobHostConfiguration(); // If this variable exists, build up a LoggerFactory with requested loggers. string instrumentationKey = ConfigurationManager.AppSettings["AppInsightsInstrumentationKey"]; if (!string.IsNullOrEmpty(instrumentationKey)) { // Set default LogCategoryFilter. var filter = new LogCategoryFilter { DefaultLevel = LogLevel.Trace }; // Wire up LoggerFactory with default filter. config.LoggerFactory = loggerFactory //.AddApplicationInsights(instrumentationKey, filter.Filter) .AddConsole(filter.Filter); config.Tracing.ConsoleLevel = TraceLevel.Verbose; // Add custom TraceLogger for Application Insights. var traceLoggerProvider = new TraceLoggerProvider(instrumentationKey); config.LoggerFactory.AddProvider(traceLoggerProvider); } // Add function filters. var extensions = config.GetService <IExtensionRegistry>(); extensions.RegisterExtension <IFunctionInvocationFilter>(new OperationIdFilter()); // Add servicebus configuration. ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Https; var serviceBusConfiguration = new ServiceBusConfiguration { MessageOptions = new OnMessageOptions { MaxConcurrentCalls = 12, AutoComplete = true } }; config.UseServiceBus(serviceBusConfiguration); // Add function trigger services. config.UseTimers(); config.UseHttp(); if (config.IsDevelopment) { config.UseDevelopmentSettings(); } // Initialize WebJob host. var host = new JobHost(config); // Run WebJob. host.RunAndBlock(); } }
static void Main(string[] args) { JobHost host = new JobHost(); host.Call(typeof(Program).GetMethod("CreateQueueMessage"), new { value = "Hello world!" }); }
private Task InvokeNoAutomaticTriggerFunction(JobHost host) { return(InvokeNoAutomaticTriggerFunction(host, CancellationToken.None)); }
private async Task Initialize() { RandomNameResolver nameResolver = new RandomNameResolver(); JobHostConfiguration hostConfiguration = new JobHostConfiguration() { NameResolver = nameResolver, TypeLocator = new FakeTypeLocator(typeof(BlobBindingEndToEndTests)), }; hostConfiguration.AddService <IWebJobsExceptionHandler>(new TestExceptionHandler()); Config = hostConfiguration; StorageAccount = CloudStorageAccount.Parse(hostConfiguration.StorageConnectionString); CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient(); BlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(ContainerName)); Assert.False(await BlobContainer.ExistsAsync()); await BlobContainer.CreateAsync(); OutputBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(OutputContainerName)); CloudBlobContainer pageBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(PageBlobContainerName)); Assert.False(await pageBlobContainer.ExistsAsync()); await pageBlobContainer.CreateAsync(); CloudBlobContainer hierarchicalBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(HierarchicalBlobContainerName)); Assert.False(await hierarchicalBlobContainer.ExistsAsync()); await hierarchicalBlobContainer.CreateAsync(); CloudBlobContainer appendBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(AppendBlobContainerName)); Assert.False(await appendBlobContainer.ExistsAsync()); await appendBlobContainer.CreateAsync(); Host = new JobHost(hostConfiguration); Host.Start(); // upload some test blobs CloudBlockBlob blob = BlobContainer.GetBlockBlobReference("blob1"); await blob.UploadTextAsync(TestData); blob = BlobContainer.GetBlockBlobReference("blob2"); await blob.UploadTextAsync(TestData); blob = BlobContainer.GetBlockBlobReference("blob3"); await blob.UploadTextAsync(TestData); blob = BlobContainer.GetBlockBlobReference("file1"); await blob.UploadTextAsync(TestData); blob = BlobContainer.GetBlockBlobReference("file2"); await blob.UploadTextAsync(TestData); blob = BlobContainer.GetBlockBlobReference("overwrite"); await blob.UploadTextAsync(TestData); // add a couple hierarchical blob paths blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/blob1"); await blob.UploadTextAsync(TestData); blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/blob2"); await blob.UploadTextAsync(TestData); blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/sub/blob3"); await blob.UploadTextAsync(TestData); blob = hierarchicalBlobContainer.GetBlockBlobReference("blob4"); await blob.UploadTextAsync(TestData); byte[] bytes = new byte[512]; byte[] testBytes = Encoding.UTF8.GetBytes(TestData); for (int i = 0; i < testBytes.Length; i++) { bytes[i] = testBytes[i]; } CloudPageBlob pageBlob = pageBlobContainer.GetPageBlobReference("blob1"); await pageBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length); pageBlob = pageBlobContainer.GetPageBlobReference("blob2"); await pageBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length); CloudAppendBlob appendBlob = appendBlobContainer.GetAppendBlobReference("blob1"); await appendBlob.UploadTextAsync(TestData); appendBlob = appendBlobContainer.GetAppendBlobReference("blob2"); await appendBlob.UploadTextAsync(TestData); appendBlob = appendBlobContainer.GetAppendBlobReference("blob3"); await appendBlob.UploadTextAsync(TestData); }
public void Initialize(JobHost host) { }
private async Task ServiceBusEndToEndInternal(Type jobContainerType, JobHost host = null, bool verifyLogs = true) { StringWriter consoleOutput = null; TextWriter hold = null; if (verifyLogs) { consoleOutput = new StringWriter(); hold = Console.Out; Console.SetOut(consoleOutput); } if (host == null) { JobHostConfiguration config = new JobHostConfiguration() { NameResolver = _nameResolver, TypeLocator = new FakeTypeLocator(jobContainerType) }; config.UseServiceBus(_serviceBusConfig); host = new JobHost(config); } string startQueueName = ResolveName(StartQueueName); string secondQueueName = startQueueName.Replace("start", "1"); string queuePrefix = startQueueName.Replace("-queue-start", ""); string firstTopicName = string.Format("{0}-topic/Subscriptions/{0}-queue-topic-1", queuePrefix); string secondTopicName = string.Format("{0}-topic/Subscriptions/{0}-queue-topic-2", queuePrefix); CreateStartMessage(_serviceBusConfig.ConnectionString, startQueueName); _topicSubscriptionCalled1 = new ManualResetEvent(initialState: false); _topicSubscriptionCalled2 = new ManualResetEvent(initialState: false); await host.StartAsync(); _topicSubscriptionCalled1.WaitOne(SBTimeout); _topicSubscriptionCalled2.WaitOne(SBTimeout); // ensure all logs have had a chance to flush await Task.Delay(3000); // Wait for the host to terminate await host.StopAsync(); host.Dispose(); Assert.Equal("E2E-SBQueue2SBQueue-SBQueue2SBTopic-topic-1", _resultMessage1); Assert.Equal("E2E-SBQueue2SBQueue-SBQueue2SBTopic-topic-2", _resultMessage2); if (verifyLogs) { Console.SetOut(hold); string[] consoleOutputLines = consoleOutput.ToString().Trim().Split(new string[] { Environment.NewLine }, StringSplitOptions.None).OrderBy(p => p).ToArray(); string[] expectedOutputLines = new string[] { "Found the following functions:", string.Format("{0}.SBQueue2SBQueue", jobContainerType.FullName), string.Format("{0}.MultipleAccounts", jobContainerType.FullName), string.Format("{0}.SBQueue2SBTopic", jobContainerType.FullName), string.Format("{0}.SBTopicListener1", jobContainerType.FullName), string.Format("{0}.SBTopicListener2", jobContainerType.FullName), "Job host started", string.Format("Executing: '{0}.SBQueue2SBQueue' - Reason: 'New ServiceBus message detected on '{1}'.'", jobContainerType.Name, startQueueName), string.Format("Executed: '{0}.SBQueue2SBQueue' (Succeeded)", jobContainerType.Name), string.Format("Executing: '{0}.SBQueue2SBTopic' - Reason: 'New ServiceBus message detected on '{1}'.'", jobContainerType.Name, secondQueueName), string.Format("Executed: '{0}.SBQueue2SBTopic' (Succeeded)", jobContainerType.Name), string.Format("Executing: '{0}.SBTopicListener1' - Reason: 'New ServiceBus message detected on '{1}'.'", jobContainerType.Name, firstTopicName), string.Format("Executed: '{0}.SBTopicListener1' (Succeeded)", jobContainerType.Name), string.Format("Executing: '{0}.SBTopicListener2' - Reason: 'New ServiceBus message detected on '{1}'.'", jobContainerType.Name, secondTopicName), string.Format("Executed: '{0}.SBTopicListener2' (Succeeded)", jobContainerType.Name), "Job host stopped" }.OrderBy(p => p).ToArray(); bool hasError = consoleOutputLines.Any(p => p.Contains("Function had errors")); if (!hasError) { Assert.Equal( string.Join(Environment.NewLine, expectedOutputLines), string.Join(Environment.NewLine, consoleOutputLines) ); } } }
// Please set the following connectionstring values in app.config // AzureJobsRuntime and AzureJobsData static void Main() { JobHost host = new JobHost(); host.RunAndBlock(); }
static int Main(string[] args) { Console.WriteLine("WebJobs BYOB Extension Analyzer v0.1"); var config = new JobHostConfiguration(); config.DashboardConnectionString = null; if (args.Length == 0) { Console.WriteLine("Error: arg0 should be path to a WebJobs extension (either .dll or .csproj)"); return(1); } var path = args[0]; var webjobsAsssembly = typeof(JobHostConfiguration).Assembly; Assembly asm = (path == "builtin") ? webjobsAsssembly : Load(path); var types = asm.GetTypes(); Console.WriteLine("============================="); foreach (var type in asm.GetTypes()) { if (typeof(IExtensionConfigProvider).IsAssignableFrom(type) && !type.IsInterface) { Console.WriteLine("Found extension: {0}", type.FullName); try { var obj = Activator.CreateInstance(type); var extension = (IExtensionConfigProvider)obj; config.AddExtension(extension); } catch (Exception e) { Console.WriteLine("ERROR: Failed to instantiate extension: " + e.Message); } } } Console.WriteLine(); // This will run the extension's Initialize() method and build up the binding graph. var host = new JobHost(config); var metadata = (JobHostMetadataProvider)host.Services.GetService(typeof(IJobHostMetadataProvider)); var rules = metadata.GetRules(); // Limit to just this extension if (asm != webjobsAsssembly) { rules = rules.Where(rule => rule.SourceAttribute.Assembly == asm).ToArray(); } HashSet <Type> attrs = new HashSet <Type>(); foreach (var rule in rules) { attrs.Add(rule.SourceAttribute); } DumpAttributes(attrs); Console.WriteLine("--------"); Console.WriteLine("Binding Rules:"); Console.WriteLine(); DumpRule(rules, Console.Out); return(0); }
public static ITestHost CreateJobHost( IOptions <DurableTaskOptions> options, string storageProvider, ILoggerProvider loggerProvider, INameResolver nameResolver, IDurableHttpMessageHandlerFactory durableHttpMessageHandler, ILifeCycleNotificationHelper lifeCycleNotificationHelper, IMessageSerializerSettingsFactory serializerSettingsFactory, IApplicationLifetimeWrapper shutdownNotificationService = null, Action <ITelemetry> onSend = null) { var config = new JobHostConfiguration { HostId = "durable-task-host" }; config.TypeLocator = TestHelpers.GetTypeLocator(); var connectionResolver = new WebJobsConnectionStringProvider(); var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(loggerProvider); // Unless otherwise specified, use legacy partition management for tests as it makes the task hubs start up faster. // These tests run on a single task hub workers, so they don't test partition management anyways, and that is tested // in the DTFx repo. if (!options.Value.StorageProvider.ContainsKey(nameof(AzureStorageOptions.UseLegacyPartitionManagement))) { options.Value.StorageProvider.Add(nameof(AzureStorageOptions.UseLegacyPartitionManagement), true); } IDurabilityProviderFactory orchestrationServiceFactory = new AzureStorageDurabilityProviderFactory( options, connectionResolver, nameResolver, loggerFactory); var extension = new DurableTaskExtension( options, loggerFactory, nameResolver, orchestrationServiceFactory, shutdownNotificationService ?? new TestHostShutdownNotificationService(), durableHttpMessageHandler, lifeCycleNotificationHelper, serializerSettingsFactory); config.UseDurableTask(extension); // Mock INameResolver for not setting EnvironmentVariables. if (nameResolver != null) { config.AddService(nameResolver); } // Performance is *significantly* worse when dashboard logging is enabled, at least // when running in the storage emulator. Disabling to keep tests running quickly. config.DashboardConnectionString = null; // Add test logger config.LoggerFactory = loggerFactory; var host = new JobHost(config); return(new FunctionsV1HostWrapper(host, options, connectionResolver)); }
/// <summary>Calls a job method.</summary> /// <param name="method">The job method to call.</param> /// <param name="arguments"> /// An object with public properties representing argument names and values to bind to parameters in the job /// method. In addition to parameter values, these may also include binding data values. /// </param> protected void Invoke(MethodInfo method, object arguments) { JobHost.Call(method, arguments); }
/// <inheritdoc /> public void BuildHost() { this._host = new JobHost(this._config.Build()); }
// Please set the following connection strings in app.config for this WebJob to run: // AzureWebJobsDashboard and AzureWebJobsStorage static void Main() { var host = new JobHost(); host.Call(typeof(Functions).GetMethod("ProcessEmails"), new { MailFolder = "Inbox" }); }
public static void Main(string[] args) { JobHost host = new JobHost(); host.Call(typeof(Program).GetMethod("SendData")); }
static void Main() { CreateTestQueues(); CreateServiceBusQueues(); CreateServiceBusTestMessage(); // This test message kicks off the sample on how to perform graceful // shutdown. It will shut down the host, so if you want to run other // samples, comment this out. //CreateShutdownTestMessage(); JobHostConfiguration config = new JobHostConfiguration() { NameResolver = new ConfigNameResolver(), }; // Demonstrates the global queue processing settings that can // be configured config.Queues.MaxPollingInterval = TimeSpan.FromSeconds(3); config.Queues.MaxDequeueCount = 3; config.Queues.BatchSize = 16; config.Queues.NewBatchThreshold = 20; // Demonstrates how queue processing can be customized further // by defining a custom QueueProcessor Factory config.Queues.QueueProcessorFactory = new CustomQueueProcessorFactory(); // Demonstrates how the console trace level can be customized config.Tracing.ConsoleLevel = TraceLevel.Verbose; // Demonstrates how a custom TraceWriter can be plugged into the // host to capture all logging/traces. config.Tracing.Tracers.Add(new CustomTraceWriter(TraceLevel.Info)); ServiceBusConfiguration serviceBusConfig = new ServiceBusConfiguration { ConnectionString = _servicesBusConnectionString, // demonstrates global customization of the default OnMessageOptions // that will be used by MessageReceivers MessageOptions = new OnMessageOptions { MaxConcurrentCalls = 10 } }; // demonstrates use of a custom MessagingProvider to perform deeper // customizations of the message processing pipeline serviceBusConfig.MessagingProvider = new CustomMessagingProvider(serviceBusConfig); config.UseServiceBus(serviceBusConfig); try { SetEnvironmentVariable(Functions.ShutDownFilePath); JobHost host = new JobHost(config); host.RunAndBlock(); } finally { ClearEnvironmentVariable(); } Console.WriteLine("\nDone"); Console.ReadLine(); }
static void Main(string[] args) { JobHost host = new JobHost(); host.RunAndBlock(); }
/// <summary> /// Calls the output trigger string /// </summary> public static async Task CallOutputTriggerStringAsync(this JobHost jobHost, MethodInfo method, string topic, IEnumerable <object> values) { var allValues = values.Select(x => x.ToString()); await jobHost.CallAsync(method, new { topic = topic, content = allValues }); }