void IExtensionConfigProvider.Initialize(ExtensionConfigContext context)
        {
            ConfigureLoaderHooks();

            context.ApplyConfig(this, "DurableTask");

            // Register the trigger bindings
            JobHostConfiguration hostConfig = context.Config;

            this.traceHelper    = new EndToEndTraceHelper(context.Trace);
            this.httpApiHandler = new HttpApiHandler(this, context.Trace);

            // Register the non-trigger bindings, which have a different model.
            var bindings = new BindingHelper(this, this.traceHelper);

            // For 202 support
            if (this.NotificationUrl == null)
            {
                this.NotificationUrl = context.GetWebhookHandler();
            }

            // Note that the order of the rules is important
            var rule = context.AddBindingRule <OrchestrationClientAttribute>()
                       .AddConverter <JObject, StartOrchestrationArgs>(bindings.JObjectToStartOrchestrationArgs);

            rule.BindToCollector <StartOrchestrationArgs>(bindings.CreateAsyncCollector);
            rule.BindToInput <DurableOrchestrationClient>(GetClient);

            context.AddBindingRule <OrchestrationTriggerAttribute>()
            .BindToTrigger(new OrchestrationTriggerAttributeBindingProvider(this, context, this.traceHelper));

            context.AddBindingRule <ActivityTriggerAttribute>()
            .BindToTrigger(new ActivityTriggerAttributeBindingProvider(this, context, this.traceHelper));
        }
 internal DurableClient(
     DurabilityProvider serviceClient,
     DurableTaskExtension config,
     HttpApiHandler httpHandler,
     DurableClientAttribute attribute)
     : this(serviceClient, httpHandler, attribute, config.MessageDataConverter, config.TraceHelper, config.Options)
 {
     this.config = config;
 }
        private readonly DurableClientAttribute attribute; // for rehydrating a Client after a webhook

        internal DurableClient(
            DurabilityProvider serviceClient,
            DurableTaskExtension config,
            HttpApiHandler httpHandler,
            DurableClientAttribute attribute)
        {
            this.config = config ?? throw new ArgumentNullException(nameof(config));

            this.client             = new TaskHubClient(serviceClient);
            this.durabilityProvider = serviceClient;
            this.traceHelper        = config.TraceHelper;
            this.httpApiHandler     = httpHandler;
            this.hubName            = attribute.TaskHub ?? config.Options.HubName;
            this.attribute          = attribute;
        }
        private void InitializeForFunctionsV1(ExtensionConfigContext context)
        {
#if !NETSTANDARD2_0
            context.ApplyConfig(this.Options, "DurableTask");

            ILogger logger = context.Config.LoggerFactory.CreateLogger(LoggerCategoryName);

            this.TraceHelper                 = new EndToEndTraceHelper(logger, this.Options.LogReplayEvents);
            this.httpApiHandler              = new HttpApiHandler(this, logger);
            this.connectionStringResolver    = new WebJobsConnectionStringProvider();
            this.LifeCycleNotificationHelper = new LifeCycleNotificationHelper(
                this.Options,
                context.Config.NameResolver,
                this.TraceHelper);
#endif
        }
        /// <summary>
        /// Internal initialization call from the WebJobs host.
        /// </summary>
        /// <param name="context">Extension context provided by WebJobs.</param>
        void IExtensionConfigProvider.Initialize(ExtensionConfigContext context)
        {
            ConfigureLoaderHooks();

            context.ApplyConfig(this, "DurableTask");

            // Register the trigger bindings
            JobHostConfiguration hostConfig = context.Config;
            ILogger logger = context.Config.LoggerFactory.CreateLogger(LoggerCategoryName);

            this.traceHelper    = new EndToEndTraceHelper(hostConfig, logger, this.LogReplayEvents);
            this.httpApiHandler = new HttpApiHandler(this, logger);

            this.lifeCycleNotificationHelper = new LifeCycleNotificationHelper(this, context);

            // Register the non-trigger bindings, which have a different model.
            var bindings = new BindingHelper(this, this.traceHelper);

            // For 202 support
            if (this.NotificationUrl == null)
            {
#pragma warning disable CS0618 // Type or member is obsolete
                this.NotificationUrl = context.GetWebhookHandler();
#pragma warning restore CS0618 // Type or member is obsolete
            }

            // Note that the order of the rules is important
            var rule = context.AddBindingRule <OrchestrationClientAttribute>()
                       .AddConverter <string, StartOrchestrationArgs>(bindings.StringToStartOrchestrationArgs)
                       .AddConverter <JObject, StartOrchestrationArgs>(bindings.JObjectToStartOrchestrationArgs);

            rule.BindToCollector <StartOrchestrationArgs>(bindings.CreateAsyncCollector);
            rule.BindToInput <DurableOrchestrationClient>(this.GetClient);

            context.AddBindingRule <OrchestrationTriggerAttribute>()
            .BindToTrigger(new OrchestrationTriggerAttributeBindingProvider(this, context, this.traceHelper));

            context.AddBindingRule <ActivityTriggerAttribute>()
            .BindToTrigger(new ActivityTriggerAttributeBindingProvider(this, context, this.traceHelper));

            AzureStorageOrchestrationServiceSettings settings = this.GetOrchestrationServiceSettings();
            this.orchestrationService = new AzureStorageOrchestrationService(settings);
            this.taskHubWorker        = new TaskHubWorker(this.orchestrationService, this, this);
            this.taskHubWorker.AddOrchestrationDispatcherMiddleware(this.OrchestrationMiddleware);

            context.Config.AddService <IOrchestrationService>(this.orchestrationService);
        }
        internal DurableClient(
            DurabilityProvider serviceClient,
            HttpApiHandler httpHandler,
            DurableClientAttribute attribute,
            MessagePayloadDataConverter messageDataConverter,
            EndToEndTraceHelper traceHelper,
            DurableTaskOptions durableTaskOptions)
        {
            this.messageDataConverter = messageDataConverter;

            this.client             = new TaskHubClient(serviceClient, this.messageDataConverter);
            this.durabilityProvider = serviceClient;
            this.traceHelper        = traceHelper;
            this.httpApiHandler     = httpHandler;
            this.durableTaskOptions = durableTaskOptions;
            this.hubName            = attribute.TaskHub ?? this.durableTaskOptions.HubName;
            this.attribute          = attribute;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DurableTaskExtension"/>.
        /// </summary>
        /// <param name="options">The configuration options for this extension.</param>
        /// <param name="loggerFactory">The logger factory used for extension-specific logging and orchestration tracking.</param>
        /// <param name="nameResolver">The name resolver to use for looking up application settings.</param>
        /// <param name="connectionStringResolver">The resolver to use for looking up connection strings.</param>
        public DurableTaskExtension(
            IOptions <DurableTaskOptions> options,
            ILoggerFactory loggerFactory,
            INameResolver nameResolver,
            IConnectionStringResolver connectionStringResolver)
        {
            // Options will be null in Functions v1 runtime - populated later.
            this.Options                  = options?.Value ?? new DurableTaskOptions();
            this.nameResolver             = nameResolver ?? throw new ArgumentNullException(nameof(nameResolver));
            this.connectionStringResolver = connectionStringResolver ?? throw new ArgumentNullException(nameof(connectionStringResolver));

            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            ILogger logger = loggerFactory.CreateLogger(LoggerCategoryName);

            this.TraceHelper    = new EndToEndTraceHelper(logger, this.Options.LogReplayEvents);
            this.httpApiHandler = new HttpApiHandler(this, logger);
            this.LifeCycleNotificationHelper = new LifeCycleNotificationHelper(options.Value, nameResolver, this.TraceHelper);
            this.isOptionsConfigured         = true;
        }