public void Initialize_PerformsExpectedRegistrations()
        {
            JobHostConfiguration config = new JobHostConfiguration();
            config.AddService<INameResolver>(new RandomNameResolver());

            ServiceBusConfiguration serviceBusConfig = new ServiceBusConfiguration();
            ServiceBusExtensionConfig serviceBusExtensionConfig = new ServiceBusExtensionConfig(serviceBusConfig);

            IExtensionRegistry extensions = config.GetService<IExtensionRegistry>();
            ITriggerBindingProvider[] triggerBindingProviders = extensions.GetExtensions<ITriggerBindingProvider>().ToArray();
            Assert.Equal(0, triggerBindingProviders.Length);
            IBindingProvider[] bindingProviders = extensions.GetExtensions<IBindingProvider>().ToArray();
            Assert.Equal(0, bindingProviders.Length);

            ExtensionConfigContext context = new ExtensionConfigContext
            {
                Config = config,
                Trace = new TestTraceWriter(TraceLevel.Verbose)
            };
            serviceBusExtensionConfig.Initialize(context);

            // ensure the ServiceBusTriggerAttributeBindingProvider was registered
            triggerBindingProviders = extensions.GetExtensions<ITriggerBindingProvider>().ToArray();
            Assert.Equal(1, triggerBindingProviders.Length);
            ServiceBusTriggerAttributeBindingProvider triggerBindingProvider = (ServiceBusTriggerAttributeBindingProvider)triggerBindingProviders[0];
            Assert.NotNull(triggerBindingProvider);

            // ensure the ServiceBusAttributeBindingProvider was registered
            bindingProviders = extensions.GetExtensions<IBindingProvider>().ToArray();
            Assert.Equal(1, bindingProviders.Length);
            ServiceBusAttributeBindingProvider bindingProvider = (ServiceBusAttributeBindingProvider)bindingProviders[0];
            Assert.NotNull(bindingProvider);
        }
            public void Initialize(ExtensionConfigContext context)
            {
                var bf = context.Config.BindingFactory;

                // Add [Test] support
                var rule = bf.BindToExactType<TestAttribute, Widget>(attr => new Widget());
                context.RegisterBindingRules<TestAttribute>(ValidateAtIndexTime, rule);
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                context.Config.RegisterBindingExtension(new SendGridAttributeBindingProvider(_sendGridConfig));
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if(context == null)
                {
                    throw new ArgumentNullException("context");
                }

                context.Config.RegisterBindingExtension(new SlackAttributeBindingProvider(_slackConfig, context.Config.NameResolver));
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                context.Config.RegisterBindingExtension(new TimerTriggerAttributeBindingProvider(_config, context.Trace));
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                context.Config.RegisterBindingExtension(new ExecutionContextBindingProvider());
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                WebHookDispatcher dispatcher = new WebHookDispatcher(_webHooksConfig, context.Host, context.Config, context.Trace);
                context.Config.RegisterBindingExtension(new WebHookTriggerAttributeBindingProvider(dispatcher));
            }
            public void Initialize(ExtensionConfigContext context)
            {
                var bf = context.Config.BindingFactory;

                // Add [Test] support                
                var rule = bf.BindToExactType<TestAttribute, string>(attr => attr.Path);
                var ruleValidate = bf.AddFilter<TestAttribute>(Filter, rule);
                var rule2 = bf.BindToExactType<TestAttribute, string>(attr => "xxx");
                context.RegisterBindingRules<TestAttribute>(ruleValidate, rule2);
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                context.Config.RegisterBindingExtension(new HttpTriggerAttributeBindingProvider());
                context.Config.RegisterBindingExtension(new ManualTriggerAttributeBindingProvider());
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                context.Config.RegisterBindingExtensions(
                    new FileTriggerAttributeBindingProvider(_filesConfig),
                    new FileAttributeBindingProvider(_filesConfig));
            }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                    throw new ArgumentNullException(nameof(context));

                // Register our extension binding providers
                context.Config.RegisterBindingExtensions(
                    new FtpAttributeBindingProvider(_ftpConfiguration, context.Trace)
                    //new FtpTriggerAttributeBindingProvider(_ftpConfiguration, context.Trace)
                );
            }
        public void Initialize(ExtensionConfigContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var converterManager = context.Config.GetOrCreateConverterManager();
            converterManager.AddConverter<TemplateNotification, Notification>(x => x);
            
            var provider = new NotificationHubAttributeBindingProvider(context.Config.NameResolver, converterManager, this);
            context.Config.RegisterBindingExtension(provider);
        }
            public void Initialize(ExtensionConfigContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                // Register our extension binding providers
                context.Config.RegisterBindingExtensions(
                    new SampleAttributeBindingProvider(), 
                    new SampleTriggerAttributeBindingProvider());

                // Register our Table binding extension
                context.Config.RegisterTableBindingExtension(new SampleTableBindingProvider());
            }
Beispiel #14
0
        public static void RegisterBindingRules <TAttribute>(
            this ExtensionConfigContext context,
            params IBindingProvider[] bindingProviders)
            where TAttribute : Attribute
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (bindingProviders == null)
            {
                throw new ArgumentNullException("bindingProviders");
            }

            IExtensionRegistry extensions = context.Config.GetService <IExtensionRegistry>();

            extensions.RegisterBindingRules <TAttribute>(bindingProviders);
        }
        /// <inheritdoc />
        public void Initialize(ExtensionConfigContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            // get the services we need to construct our binding providers
            INameResolver nameResolver = context.Config.GetService<INameResolver>();
            IExtensionRegistry extensions = context.Config.GetService<IExtensionRegistry>();

            // register our trigger binding provider
            ServiceBusTriggerAttributeBindingProvider triggerBindingProvider = new ServiceBusTriggerAttributeBindingProvider(nameResolver, _serviceBusConfig);
            extensions.RegisterExtension<ITriggerBindingProvider>(triggerBindingProvider);

            // register our binding provider
            ServiceBusAttributeBindingProvider bindingProvider = new ServiceBusAttributeBindingProvider(nameResolver, _serviceBusConfig);
            extensions.RegisterExtension<IBindingProvider>(bindingProvider);
        }
Beispiel #16
0
        /// <summary>
        /// Apply configuration for this extension.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="target">an existing object that the settings will get JSON serialized onto</param>
        /// <param name="section">specifies a section from the overall config that should apply to this object.</param>
        public static void ApplyConfig(this ExtensionConfigContext context, object target, string section = null)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            JObject hostMetadata = context.GetConfig(target, section);

            if (hostMetadata == null)
            {
                return;
            }

            JsonConvert.PopulateObject(hostMetadata.ToString(), target);
        }
Beispiel #17
0
        /// <summary>
        /// Get the configuration object for this extension.
        /// </summary>
        /// <param name="context"></param>
        /// /// <param name="target"></param>
        /// <param name="section"></param>
        /// <returns></returns>
        public static JObject GetConfig(this ExtensionConfigContext context, object target, string section = null)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            JObject hostMetadata = context.Config.HostConfigMetadata;

            if (hostMetadata == null)
            {
                return(null);
            }

            if (section == null)
            {
                // By convention, an extension named "FooConfiguration" reads the "Foo" section.
                if (target is IExtensionConfigProvider)
                {
                    string name   = target.GetType().Name;
                    var    suffix = "Configuration";
                    if (name.EndsWith(suffix, StringComparison.Ordinal))
                    {
                        section = name.Substring(0, name.Length - suffix.Length);
                    }
                }
            }

            if (section != null)
            {
                JToken value;
                if (hostMetadata.TryGetValue(section, StringComparison.OrdinalIgnoreCase, out value))
                {
                    hostMetadata = value as JObject;
                }
            }

            return(hostMetadata);
        }
Beispiel #18
0
        /// <summary>
        /// Register a set of rules to handle binding to a given attribute.
        /// </summary>
        /// <typeparam name="TAttribute">The attribute to bind to</typeparam>
        /// <param name="context"></param>
        /// <param name="validator">a validator function to invoke on the attribute before runtime. </param>
        /// <param name="bindingProviders">list of binding providers to handle this attribute.
        /// If none of these handle the attribute, an error is thrown at indexing. </param>
        public static void RegisterBindingRules <TAttribute>(
            this ExtensionConfigContext context,
            Action <TAttribute, Type> validator,
            params IBindingProvider[] bindingProviders)
            where TAttribute : Attribute
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (validator == null)
            {
                throw new ArgumentNullException("validator");
            }
            if (bindingProviders == null)
            {
                throw new ArgumentNullException("bindingProviders");
            }

            IExtensionRegistry extensions   = context.Config.GetService <IExtensionRegistry>();
            INameResolver      nameResolver = context.Config.NameResolver;

            extensions.RegisterBindingRules <TAttribute>(validator, nameResolver, bindingProviders);
        }
        public static async Task<JobHostContext> CreateAndLogHostStartedAsync(
            JobHost host,
            IStorageAccountProvider storageAccountProvider,
            IQueueConfiguration queueConfiguration,
            ITypeLocator typeLocator,
            IJobActivator activator,
            INameResolver nameResolver,
            IConsoleProvider consoleProvider,
            JobHostConfiguration config,
            CancellationToken shutdownToken,
            CancellationToken cancellationToken,
            IHostIdProvider hostIdProvider = null,
            FunctionExecutor functionExecutor = null,
            IFunctionIndexProvider functionIndexProvider = null,
            IBindingProvider bindingProvider = null,
            IHostInstanceLoggerProvider hostInstanceLogerProvider = null,
            IFunctionInstanceLoggerProvider functionInstanceLoggerProvider = null,
            IFunctionOutputLoggerProvider functionOutputLoggerProvider = null,
            IBackgroundExceptionDispatcher backgroundExceptionDispatcher = null,
            SingletonManager singletonManager = null)
        {
            if (hostIdProvider == null)
            {
                hostIdProvider = new DynamicHostIdProvider(storageAccountProvider, () => functionIndexProvider);
            }

            IExtensionTypeLocator extensionTypeLocator = new ExtensionTypeLocator(typeLocator);
            if (backgroundExceptionDispatcher == null)
            {
                backgroundExceptionDispatcher = BackgroundExceptionDispatcher.Instance;
            }
            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 
            // TraceWriter specified on 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);

            ExtensionConfigContext context = new ExtensionConfigContext
            {
                Config = config,
                Trace = trace,
                Host = host
            };
            InvokeExtensionConfigProviders(context);

            IExtensionRegistry extensions = config.GetExtensions();
            ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver,
                storageAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, backgroundExceptionDispatcher,
                messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, extensions, trace);

            if (bindingProvider == null)
            {
                bindingProvider = DefaultBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, extensions);
            }

            DefaultLoggerProvider loggerProvider = new DefaultLoggerProvider(storageAccountProvider, trace);

            if (singletonManager == null)
            {
                singletonManager = new SingletonManager(storageAccountProvider, backgroundExceptionDispatcher, config.Singleton, trace, config.NameResolver);
            }
            
            using (CancellationTokenSource combinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, shutdownToken))
            {
                CancellationToken combinedCancellationToken = combinedCancellationSource.Token;

                await WriteSiteExtensionManifestAsync(combinedCancellationToken);

                IStorageAccount dashboardAccount = await storageAccountProvider.GetDashboardAccountAsync(combinedCancellationToken);

                IHostInstanceLogger hostInstanceLogger = null;
                if (hostInstanceLogerProvider != null)
                {
                    hostInstanceLogger = await hostInstanceLogerProvider.GetAsync(combinedCancellationToken);
                }
                else
                {
                    hostInstanceLogger = await((IHostInstanceLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken);
                }

                IFunctionInstanceLogger functionInstanceLogger = null;
                if (functionInstanceLoggerProvider != null)
                {
                    functionInstanceLogger = await functionInstanceLoggerProvider.GetAsync(combinedCancellationToken);
                }
                else
                {
                    functionInstanceLogger = (IFunctionInstanceLogger)(await((IFunctionInstanceLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken));
                }

                IFunctionOutputLogger functionOutputLogger = null;
                if (functionOutputLoggerProvider != null)
                {
                    functionOutputLogger = await functionOutputLoggerProvider.GetAsync(combinedCancellationToken);
                }
                else
                {
                    functionOutputLogger = (IFunctionOutputLogger)(await((IFunctionOutputLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken));
                }

                if (functionExecutor == null)
                {
                    functionExecutor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, backgroundExceptionDispatcher, trace);
                }

                if (functionIndexProvider == null)
                {
                    functionIndexProvider = new FunctionIndexProvider(typeLocator, triggerBindingProvider, bindingProvider, activator, functionExecutor, extensions, singletonManager);
                }

                IFunctionIndex functions = await functionIndexProvider.GetAsync(combinedCancellationToken);
                IListenerFactory functionsListenerFactory = new HostListenerFactory(functions.ReadAll(), singletonManager, activator, nameResolver, trace);

                IFunctionExecutor hostCallExecutor;
                IListener listener;
                HostOutputMessage hostOutputMessage;

                if (dashboardAccount != null)
                {
                    string hostId = await hostIdProvider.GetHostIdAsync(cancellationToken);

                    string sharedQueueName = HostQueueNames.GetHostQueueName(hostId);
                    IStorageQueueClient dashboardQueueClient = dashboardAccount.CreateQueueClient();
                    IStorageQueue sharedQueue = dashboardQueueClient.GetQueueReference(sharedQueueName);
                    IListenerFactory sharedQueueListenerFactory = new HostMessageListenerFactory(sharedQueue,
                        queueConfiguration, backgroundExceptionDispatcher, 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, backgroundExceptionDispatcher, 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,
                        backgroundExceptionDispatcher, shutdownToken, functionExecutor);
                    IListenerFactory hostListenerFactory = new CompositeListenerFactory(functionsListenerFactory,
                        sharedQueueListenerFactory, instanceQueueListenerFactory);
                    listener = CreateHostListener(hostListenerFactory, heartbeatCommand, backgroundExceptionDispatcher, shutdownToken);

                    // Publish this to Azure logging account so that a web dashboard can see it. 
                    await LogHostStartedAsync(functions, hostOutputMessage, hostInstanceLogger, combinedCancellationToken);
                }
                else
                {
                    hostCallExecutor = new ShutdownFunctionExecutor(shutdownToken, functionExecutor);

                    IListener factoryListener = new ListenerFactoryListener(functionsListenerFactory);
                    IListener shutdownListener = new ShutdownListener(shutdownToken, factoryListener);
                    listener = shutdownListener;

                    hostOutputMessage = new DataOnlyHostOutputMessage();
                }

                functionExecutor.HostOutputMessage = hostOutputMessage;

                IEnumerable<FunctionDescriptor> descriptors = functions.ReadAllDescriptors();
                int descriptorsCount = descriptors.Count();

                if (descriptorsCount == 0)
                {
                    trace.Warning("No functions found. Try making job classes and methods public.", 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);
            }
        }
        private static void InvokeExtensionConfigProviders(ExtensionConfigContext context)
        {
            IExtensionRegistry extensions = context.Config.GetExtensions();

            IEnumerable<IExtensionConfigProvider> configProviders = extensions.GetExtensions(typeof(IExtensionConfigProvider)).Cast<IExtensionConfigProvider>();
            foreach (IExtensionConfigProvider configProvider in configProviders)
            {
                configProvider.Initialize(context);
            }
        }
        void IExtensionConfigProvider.Initialize(ExtensionConfigContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            // Deferred list
            foreach (var action in _deferredWork)
            {
                action(context.Config);
            }
            _deferredWork.Clear();

            // get the services we need to construct our binding providers
            INameResolver nameResolver = context.Config.NameResolver;
            IExtensionRegistry extensions = context.Config.GetService<IExtensionRegistry>();

            IConverterManager cm = context.Config.GetService<IConverterManager>();
            cm.AddConverter<string, EventData>(ConvertString2EventData);
            cm.AddConverter<EventData, string>(ConvertEventData2String);
            cm.AddConverter<byte[], EventData>(ConvertBytes2EventData); // direct, handles non-string representations

            var bf = new BindingFactory(nameResolver, cm);

            // register our trigger binding provider
            var triggerBindingProvider = new EventHubTriggerAttributeBindingProvider(nameResolver, cm, this);
            extensions.RegisterExtension<ITriggerBindingProvider>(triggerBindingProvider);

            // register our binding provider
            var ruleOutput = bf.BindToAsyncCollector<EventHubAttribute, EventData>(BuildFromAttribute);
            extensions.RegisterBindingRules<EventHubAttribute>(ruleOutput);
        }
            public void Initialize(ExtensionConfigContext context)
            {
                var bf = context.Config.BindingFactory;

                // Add [Test] support
                var rule1 = bf.BindToExactType<TestAttribute, Widget>(attr => new Widget());
                var rule2 = bf.BindToExactType<TestAttribute, Widget2>(attr => new Widget2());
                var rule2Validator = bf.AddValidator<TestAttribute>(LocalValidator, rule2);

                context.RegisterBindingRules<TestAttribute>(rule2Validator, rule1);
            }