/// <summary>
        /// Configures the default set of Functions Worker services to the provided <see cref="IHostBuilder"/>,
        /// with a delegate to configure a provided <see cref="HostBuilderContext"/> and an <see cref="IFunctionsWorkerApplicationBuilder"/>,
        /// and a delegate to configure the <see cref="WorkerOptions"/>.
        /// <list type="bullet">
        ///     <item><description>A default set of converters.</description></item>
        ///     <item><description>Configures the default <see cref="JsonSerializerOptions"/> to ignore casing on property names.</description></item>
        ///     <item><description>Integration with Azure Functions logging.</description></item>
        ///     <item><description>Adds environment variables as a configuration source.</description></item>
        ///     <item><description>Adds command line arguments as a configuration source.</description></item>
        ///     <item><description>Output binding middleware and features.</description></item>
        ///     <item><description>Function execution middleware.</description></item>
        ///     <item><description>Default gRPC support.</description></item>
        /// </list>
        /// </summary>
        /// <param name="builder">The <see cref="IHostBuilder"/> to configure.</param>
        /// <param name="configure">A delegate that will be invoked to configure the provided <see cref="HostBuilderContext"/> and an <see cref="IFunctionsWorkerApplicationBuilder"/>.</param>
        /// <param name="configureOptions">A delegate that will be invoked to configure the provided <see cref="WorkerOptions"/>.</param>
        /// <returns>The <see cref="IHostBuilder"/>.</returns>
        public static IHostBuilder ConfigureFunctionsWorkerDefaults(this IHostBuilder builder, Action <HostBuilderContext, IFunctionsWorkerApplicationBuilder> configure, Action <WorkerOptions> configureOptions)
        {
            builder
            .ConfigureHostConfiguration(config =>
            {
                // Add AZURE_FUNCTIONS_ prefixed environment variables
                config.AddEnvironmentVariables("AZURE_FUNCTIONS_");
            })
            .ConfigureAppConfiguration(configBuilder =>
            {
                configBuilder.AddEnvironmentVariables();

                var cmdLine = Environment.GetCommandLineArgs();
                RegisterCommandLine(configBuilder, cmdLine);
            })
            .ConfigureServices((context, services) =>
            {
                IFunctionsWorkerApplicationBuilder appBuilder = services.AddFunctionsWorkerDefaults(configureOptions);

                // Call the provided configuration prior to adding default middleware
                configure(context, appBuilder);

                // Add default middleware
                appBuilder.UseDefaultWorkerMiddleware();
            });

            return(builder);
        }
예제 #2
0
        public void ConfigureWorker(IFunctionsWorkerApplicationBuilder builder)
        {
            if (ConfigureAuthentication)
            {
                builder.UseAuthorization();
            }

            builder.UseFunctionExecutionMiddleware();
        }
        public static IHostBuilder ConfigureFunctionsWorker(this IHostBuilder builder, Action <HostBuilderContext, IFunctionsWorkerApplicationBuilder> configure, Action <WorkerOptions> configureOptions)
        {
            builder.ConfigureServices((context, services) =>
            {
                IFunctionsWorkerApplicationBuilder appBuilder = services.AddFunctionsWorker(configureOptions);

                configure(context, appBuilder);
            });

            return(builder);
        }
        /// <summary>
        /// Configures a middleware for Azure App Configuration to use activity-based refresh for data configured in the provider.
        /// </summary>
        /// <param name="builder">An instance of <see cref="IFunctionsWorkerApplicationBuilder"/></param>
        public static IFunctionsWorkerApplicationBuilder UseAzureAppConfiguration(this IFunctionsWorkerApplicationBuilder builder)
        {
            // Verify if AddAzureAppConfiguration was done before calling UseAzureAppConfiguration.
            // We use the IConfigurationRefresherProvider to make sure if the required services were added.
            if (!builder.Services.Any(service => service.ServiceType == typeof(IConfigurationRefresherProvider)))
            {
                throw new InvalidOperationException($"Unable to find the required services. Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(AzureAppConfigurationExtensions.AddAzureAppConfiguration)}()' inside the call to 'ConfigureServices(...)' in the application startup code.");
            }

            return(builder.UseMiddleware <AzureAppConfigurationRefreshMiddleware>());
        }
예제 #5
0
        /// <summary>
        /// Configures the <see cref="IFunctionsWorkerApplicationBuilder"/> to use the provided inline middleware delegate.
        /// </summary>
        /// <param name="builder">The <see cref="IFunctionsWorkerApplicationBuilder"/> to configure.</param>
        /// <param name="middleware">The middleware to add to the invocation pipeline.</param>
        /// <returns>The same <see cref="IFunctionsWorkerApplicationBuilder"/> for chaining.</returns>
        public static IFunctionsWorkerApplicationBuilder UseMiddleware(this IFunctionsWorkerApplicationBuilder builder, Func <FunctionContext, Func <Task>, Task> middleware)
        {
            builder.Use(next =>
            {
                return(context =>
                {
                    return middleware(context, () => next.Invoke(context));
                });
            });

            return(builder);
        }
        // PREVIEW: this class is temporary
        public static IFunctionsWorkerApplicationBuilder UseAuthorization(this IFunctionsWorkerApplicationBuilder builder)
        {
            builder.Services.AddSingleton <AuthenticationMiddleware>();

            return(builder.Use(next =>
            {
                return context =>
                {
                    var middleware = context.InstanceServices.GetRequiredService <AuthenticationMiddleware>();
                    return middleware.InvokeAsync(context, next);
                };
            }));
        }
        /// <summary>
        /// The functions worker uses the Azure SDK's ObjectSerializer to abstract away all JSON serialization. This allows you to
        /// swap out the default System.Text.Json implementation for the Newtonsoft.Json implementation.
        /// To do so, add the Microsoft.Azure.Core.NewtonsoftJson nuget package and then update the WorkerOptions.Serializer property.
        /// This method updates the Serializer to use Newtonsoft.Json. Call /api/HttpFunction to see the changes.
        /// </summary>
        public static IFunctionsWorkerApplicationBuilder UseNewtonsoftJson(this IFunctionsWorkerApplicationBuilder builder)
        {
            builder.Services.Configure <WorkerOptions>(workerOptions =>
            {
                var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
                settings.ContractResolver  = new CamelCasePropertyNamesContractResolver();
                settings.NullValueHandling = NullValueHandling.Ignore;

                workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
            });

            return(builder);
        }
        /// <summary>
        /// Calling ConfigureFunctionsWorkerDefaults() configures the Functions Worker to use System.Text.Json for all JSON
        /// serialization and sets JsonSerializerOptions.PropertyNameCaseInsensitive = true;
        /// This method uses DI to modify the JsonSerializerOptions. Call /api/HttpFunction to see the changes.
        /// </summary>
        public static IFunctionsWorkerApplicationBuilder ConfigureSystemTextJson(this IFunctionsWorkerApplicationBuilder builder)
        {
            builder.Services.Configure <JsonSerializerOptions>(jsonSerializerOptions =>
            {
                jsonSerializerOptions.PropertyNamingPolicy   = JsonNamingPolicy.CamelCase;
                jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
                jsonSerializerOptions.ReferenceHandler       = ReferenceHandler.Preserve;

                // override the default value
                jsonSerializerOptions.PropertyNameCaseInsensitive = false;
            });

            return(builder);
        }
예제 #9
0
        /// <summary>
        /// Configures the core set of Functions Worker services to the provided <see cref="IHostBuilder"/>,
        /// with a delegate to configure a provided <see cref="HostBuilderContext"/> and an <see cref="IFunctionsWorkerApplicationBuilder"/>,
        /// and a delegate to configure the <see cref="WorkerOptions"/>.
        /// NOTE: You must configure required services for an operational worker when using this method.
        /// </summary>
        /// <param name="builder">The <see cref="IHostBuilder"/> to configure.</param>
        /// <param name="configure">A delegate that will be invoked to configure the provided <see cref="HostBuilderContext"/> and an <see cref="IFunctionsWorkerApplicationBuilder"/>.</param>
        /// <param name="configureOptions">A delegate that will be invoked to configure the provided <see cref="WorkerOptions"/>.</param>
        /// <returns>The <see cref="IHostBuilder"/>.</returns>
        public static IHostBuilder ConfigureFunctionsWorker(this IHostBuilder builder, Action <HostBuilderContext, IFunctionsWorkerApplicationBuilder> configure, Action <WorkerOptions> configureOptions)
        {
            if (configure is null)
            {
                throw new ArgumentNullException(nameof(configure));
            }

            builder.ConfigureServices((context, services) =>
            {
                IFunctionsWorkerApplicationBuilder appBuilder = services.AddFunctionsWorkerCore(configureOptions);

                configure(context, appBuilder);
            });

            return(builder);
        }
        internal static IFunctionsWorkerApplicationBuilder UseConverterMiddleware(this IFunctionsWorkerApplicationBuilder builder)
        {
            builder.Services.AddSingleton <ConverterMiddleware>();

            builder.Use(next =>
            {
                return(context =>
                {
                    var middleware = context.InstanceServices.GetRequiredService <ConverterMiddleware>();

                    return middleware.Invoke(context, next);
                });
            });

            return(builder);
        }
예제 #11
0
        /// <summary>
        /// Configures the <see cref="IFunctionsWorkerApplicationBuilder"/> to use the provided middleware type.
        /// </summary>
        /// <param name="builder">The <see cref="IFunctionsWorkerApplicationBuilder"/> to configure.</param>
        /// <returns>The same instance of the <see cref="IFunctionsWorkerApplicationBuilder"/> for chanining.</returns>
        public static IFunctionsWorkerApplicationBuilder UseMiddleware <T>(this IFunctionsWorkerApplicationBuilder builder)
            where T : class, IFunctionsWorkerMiddleware
        {
            builder.Services.AddSingleton <T>();

            builder.Use(next =>
            {
                return(context =>
                {
                    var middleware = context.InstanceServices.GetRequiredService <T>();

                    return middleware.Invoke(context, next);
                });
            });

            return(builder);
        }
예제 #12
0
        /// <summary>
        /// Configures the <see cref="IFunctionsWorkerApplicationBuilder"/> to use the default <see cref="OutputBindingsMiddleware"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IFunctionsWorkerApplicationBuilder"/> to configure.</param>
        /// <returns>The same instance of the <see cref="IFunctionsWorkerApplicationBuilder"/> for chanining.</returns>
        public static IFunctionsWorkerApplicationBuilder UseOutputBindingsMiddleware(this IFunctionsWorkerApplicationBuilder builder)
        {
            if (builder.Services.Any(d => d.ServiceType == typeof(OutputBindingsMiddleware)))
            {
                return(builder);
            }

            builder.Services.AddSingleton <OutputBindingsMiddleware>(p => throw new InvalidOperationException($"Type {nameof(OutputBindingsMiddleware)} cannot be resolved using the container."));

            builder.Use(next =>
            {
                return(context =>
                {
                    return OutputBindingsMiddleware.Invoke(context, next);
                });
            });

            return(builder);
        }
        /// <summary>
        /// Configures the <see cref="IFunctionsWorkerApplicationBuilder"/> to use the default <see cref="OutputBindingsMiddleware"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IFunctionsWorkerApplicationBuilder"/> to configure.</param>
        /// <returns>The same instance of the <see cref="IFunctionsWorkerApplicationBuilder"/> for chanining.</returns>
        public static IFunctionsWorkerApplicationBuilder UseOutputBindingsMiddleware(this IFunctionsWorkerApplicationBuilder builder)
        {
            if (builder.Services.Any(d => d.ServiceType == typeof(OutputBindingsMiddleware)))
            {
                return(builder);
            }

            builder.Services.AddSingleton <OutputBindingsMiddleware>();

            builder.Use(next =>
            {
                return(context =>
                {
                    var middleware = context.InstanceServices.GetRequiredService <OutputBindingsMiddleware>();

                    return middleware.Invoke(context, next);
                });
            });

            return(builder);
        }
        public static IFunctionsWorkerApplicationBuilder UseFunctionExecutionMiddleware(this IFunctionsWorkerApplicationBuilder builder)
        {
            // We want to keep this internal for now.
            builder.UseConverterMiddleware();

            builder.Services.AddSingleton <FunctionExecutionMiddleware>();

            builder.Use(next =>
            {
                return(context =>
                {
                    var middleware = context.InstanceServices.GetRequiredService <FunctionExecutionMiddleware>();

                    return middleware.Invoke(context);
                });
            });

            return(builder);
        }
예제 #15
0
        /// <summary>
        /// Configure Functions worker
        /// </summary>
        /// <param name="builder"></param>
        internal void ConfigureWorker(IFunctionsWorkerApplicationBuilder builder)
        {
            #region Middleware section to demonstrate format response scenario

            builder.Use(next =>
            {
                return(context =>
                {
                    var middleware = context.InstanceServices.GetRequiredService <FormatResponseMiddleware>();

                    return middleware.Invoke(context, next);
                });
            });

            builder.UseFunctionExecutionMiddleware();

            #endregion

            #region Middleware section to demonstrate bypass scenario

            builder.Use(next =>
            {
                return(context =>
                {
                    var bypassMiddleware = context.InstanceServices.GetRequiredService <BypassMiddleware>();

                    return bypassMiddleware.Invoke(context, next);
                });
            });

            builder.UseFunctionExecutionMiddleware();

            #endregion

            #region Middleware section to demonstrate pass through scenario

            builder.Use(next =>
            {
                return(context =>
                {
                    var passThroughMiddleware = context.InstanceServices.GetRequiredService <PassThroughMiddleware>();

                    return passThroughMiddleware.Invoke(context, next);
                });
            });

            builder.UseFunctionExecutionMiddleware();

            #endregion

            #region Middleware section to demonstrate Exception handling scenario

            builder.Use(next =>
            {
                return(context =>
                {
                    var exceptionHandlerMiddleware = context.InstanceServices.GetRequiredService <ExceptionHandlerMiddleware>();

                    return exceptionHandlerMiddleware.Invoke(context, next);
                });
            });

            builder.UseFunctionExecutionMiddleware();

            #endregion
        }
        public static IFunctionsWorkerApplicationBuilder UseGrpc(this IFunctionsWorkerApplicationBuilder builder)
        {
            builder.Services.AddGrpc();

            return(builder);
        }
예제 #17
0
 /// <summary>
 /// Configures the <see cref="IFunctionsWorkerApplicationBuilder"/> to use the default set of middleware used by the worker, in the following order:
 /// <list type="number">
 ///     <item>
 ///         <description><see cref="OutputBindingsMiddleware"/></description>
 ///     </item>
 ///     <item>
 ///         <description><see cref="FunctionExecutionMiddleware"/></description>
 ///     </item>
 /// </list>
 /// </summary>
 /// <param name="builder">The <see cref="IFunctionsWorkerApplicationBuilder"/> to configure.</param>
 /// <returns>The same instance of the <see cref="IFunctionsWorkerApplicationBuilder"/> for chanining.</returns>
 public static IFunctionsWorkerApplicationBuilder UseDefaultWorkerMiddleware(this IFunctionsWorkerApplicationBuilder builder)
 {
     return(builder.UseOutputBindingsMiddleware()
            .UseFunctionExecutionMiddleware());
 }