Skip to content
Permalink
main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
// Copyright 2020, Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Reflection;
using System.Threading.Tasks;
namespace Google.Cloud.Functions.Hosting
{
/// <summary>
/// The entry point for the hosting package. This is used automatically by the entry point generated by MS Build
/// targets within the Google.Cloud.Functions.Hosting NuGet package.
/// </summary>
public static class EntryPoint
{
/// <summary>
/// The environment variable used to detect the function target name, when not otherwise provided.
/// </summary>
public const string FunctionTargetEnvironmentVariable = "FUNCTION_TARGET";
/// <summary>
/// The environment variable used to detect the port to listen on.
/// </summary>
public const string PortEnvironmentVariable = "PORT";
/// <summary>
/// Starts a web server to serve the function in the specified assembly. This method is called
/// automatically be the generated entry point.
/// </summary>
/// <param name="functionAssembly">The assembly containing the function to execute.</param>
/// <param name="args">Arguments to parse </param>
/// <returns>A task representing the asynchronous operation.
/// The result of the task is an exit code for the process, which is 0 for success or non-zero
/// for any failures.
/// </returns>
public static async Task<int> StartAsync(Assembly functionAssembly, string[] args)
{
// Clear out the ASPNETCORE_URLS environment variable in order to avoid a warning when we start the server.
// An alternative would be to *use* the environment variable, but as it's populated (with a non-ideal value) by
// default, I suspect that would be tricky.
Environment.SetEnvironmentVariable("ASPNETCORE_URLS", null);
// Guess the function type by creating a configuration with just the environment variables and command line
// arguments in it. We do this so we can work out the function startup classes to use - and then validate that
// when we've used those functions startups and worked out the actual function target, the set of
// function startups is still valid. Note that it's possible for this to return null, if an assembly-specified
// function startup determines the actual function target. That's valid, so long as the function target doesn't
// later require any specific startups. (It would be very, very rare for a startup to affect which function is
// used, but I can imagine some scenarios where it's useful.)
var expectedFunctionTarget = GuessFunctionTarget();
// TODO: Catch exceptions and return 1, or just let the exception propagate? It probably
// doesn't matter much. Potentially catch exceptions during configuration, but let any
// during web server execution propagate.
var host = Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webHostBuilder => webHostBuilder
.ConfigureAppConfiguration(builder => builder.AddFunctionsEnvironment().AddFunctionsCommandLine(args))
.ConfigureLogging((context, logging) => logging.ClearProviders().AddFunctionsConsoleLogging(context))
.ConfigureKestrelForFunctionsFramework()
.ConfigureServices((context, services) => services.AddFunctionTarget(context, functionAssembly))
.UseFunctionsStartups(functionAssembly, expectedFunctionTarget)
.Configure((context, app) => app.UseFunctionsFramework(context, validateStartups: true)))
.Build();
await host.RunAsync();
return 0;
Type? GuessFunctionTarget()
{
var configuration = new ConfigurationBuilder()
.AddFunctionsEnvironment()
.AddFunctionsCommandLine(args)
.Build();
return HostingInternals.TryGetFunctionTarget(configuration, functionAssembly);
}
}
}
}