forked from GoogleCloudPlatform/functions-framework-dotnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EntryPoint.cs
93 lines (86 loc) · 4.85 KB
/
EntryPoint.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// 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);
}
}
}
}