static void Main()
        {
            CreateDemoData();

            JobHost host = new JobHost();
            host.RunAndBlock();
        }
Пример #2
0
        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);
            }
        }
Пример #4
0
            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;
 }
Пример #6
0
            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();
        }
Пример #8
0
 public void StartAsync_WhenNotStarted_DoesNotThrow()
 {
     // Arrange
     using (JobHost host = new JobHost(CreateConfiguration()))
     {
         // Act & Assert
         host.StartAsync().GetAwaiter().GetResult();
     }
 }
Пример #9
0
        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);
            }
        }
Пример #13
0
            public void DoesNotCallStartIfWorkIsAlreadyScheduledOrCompleted()
            {
                var tcs = new TaskCompletionSource<object>();
                tcs.SetResult(null);

                var task = tcs.Task;

                var host = new JobHost();

                Assert.DoesNotThrow(() => host.DoWork(task));
            }
Пример #14
0
        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();
        }
Пример #16
0
        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);
        }
Пример #22
0
        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);
            }
        }
Пример #23
0
        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();
        }
Пример #24
0
        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);
            }
        }
Пример #28
0
            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);
        }
Пример #30
0
 /// <summary>
 /// defult ctor
 /// </summary>
 public AzureJobHost()
 {
     _jobHost = new JobHost();
 }
Пример #31
0
        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);
        }
Пример #32
0
 public FunctionsV1HostWrapper(JobHost innerHost)
 {
     this.innerHost = innerHost ?? throw new ArgumentNullException(nameof(innerHost));
 }
Пример #33
0
        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);
        }
Пример #34
0
 /// <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();
            }
Пример #37
0
        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));
            }
        }
Пример #38
0
 public void Initialize(JobHost host)
 {
     UnhandledExceptionInfos = new List <ExceptionDispatchInfo>();
     TimeoutExceptionInfos   = new List <ExceptionDispatchInfo>();
 }
Пример #39
0
 public void Test(JobHost <ConfigNullOutParam> host)
 {
     host.Call("WriteString");
     // Convert was never called
 }
Пример #40
0
        [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}");
                }
        }
Пример #41
0
 /// <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);
 }
Пример #42
0
 /// <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);
 }
Пример #43
0
 private void SetupJobHost()
 {
     JobHost.Configure(_configurator);
 }
Пример #44
0
        static void Main(string[] args)
        {
            var host = new JobHost();

            host.RunAndBlock();
        }
Пример #45
0
        // 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!" });
    }
Пример #47
0
 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);
            }
Пример #49
0
 public void Initialize(JobHost host)
 {
 }
Пример #50
0
        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)
                        );
                }
            }
        }
Пример #51
0
        // Please set the following connectionstring values in app.config
        // AzureJobsRuntime and AzureJobsData
        static void Main()
        {
            JobHost host = new JobHost();

            host.RunAndBlock();
        }
Пример #52
0
        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));
        }
Пример #54
0
 /// <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);
 }
Пример #55
0
 /// <inheritdoc />
 public void BuildHost()
 {
     this._host = new JobHost(this._config.Build());
 }
Пример #56
0
        // 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" });
        }
Пример #57
0
        public static void Main(string[] args)
        {
            JobHost host = new JobHost();

            host.Call(typeof(Program).GetMethod("SendData"));
        }
Пример #58
0
        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();
        }
Пример #59
0
 static void Main(string[] args)
 {
     JobHost host = new JobHost();
     host.RunAndBlock();
 }
Пример #60
0
 /// <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 });
 }