using System; using System.Text.Json.Serialization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace ScrumTaskboard { public class Startup { /// /// Default constructor that "just" sets the configuration (needed by default for the ASP.NetCore Webservice) /// /// configuration for the new Startup object public Startup(IConfiguration configuration) { Configuration = configuration; } //Default getter for the configuration public IConfiguration Configuration { get; } /// /// This method gets called by the runtime. /// It's used to add services to the container. /// /// public void ConfigureServices(IServiceCollection services) { //CORS (Cross Origin Resource Sharing) controls from where a service can be accessed //Here we allow access from every origin by adding a policy called "AllowAll" that allows access form every origin with every method and any headers services.AddCors(o => o.AddPolicy("AllowAll", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); })); //JSON parsing options control how JSON is parsed to get input or send output from/to the API endpoints //Here we allow null values for parameters and add a Enum converter for the "ScrumPrio" Enum services.AddMvc().AddJsonOptions(o => { o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); o.JsonSerializerOptions.IgnoreNullValues = true; }); //Adds the PostgreSQL based database context to provide database communication services.AddScoped(serviceProvider => new TaskContext( new DbContextOptionsBuilder() .UseNpgsql(GetConnectionString()) .Options)); //Default Service call that adds all controllers (and thereby API endpoints) to the service services.AddControllers(); //OpenAPI Document settings for autogenerating the OpenAPI v3 documentation //Here we set the basic information for the documentation - mainly: version, title, description and TOS services.AddOpenApiDocument( config => { config.PostProcess = document => { document.Info.Version = "v1"; document.Info.Title = "Scrum Taskboard API"; document.Info.Description = "A RESTful API for the Scrum Taskboard Backend"; document.Info.TermsOfService = "None"; }; }); } /// /// This method gets called by the runtime. /// This method gets used to configure the HTTP request pipeline. /// /// /// public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //Ensure the existance of all tabels in the database (by creating them if they're missing) using (var serviceScope = app.ApplicationServices.GetService().CreateScope()) { var context = serviceScope.ServiceProvider.GetRequiredService(); context.Database.EnsureCreated(); } //Checks is developer mode is enabled in the env and adds the developer only exception page for debugging if it is enabled if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //Use the previously created "AllowAll" CORS policy app.UseCors("AllowAll"); //Use the default ASP.NetCore routing app.UseRouting(); //Use the endpoints provided by the controllers and map their urls accordingly app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); //Use the configured OpenAPI document config and add the url schemes for http and https. app.UseOpenApi(a => { a.PostProcess = (document, _) => { document.Schemes = new[] { NSwag.OpenApiSchema.Https, NSwag.OpenApiSchema.Http }; document.Servers.Add(new NSwag.OpenApiServer { Description = "Demo Server", Url = "https://taskboard.dev.nig.gl/" }); }; }); //Use the SwaggerUi v3 to provide a SwaggerUI based API explorer at "/swagger" app.UseSwaggerUi3(options => { options.Path = "/swagger"; }); //Use Redoc to provide a ReDoc based API explorer at "/redoc" app.UseReDoc(options => { options.Path = "/redoc"; }); } /// /// Creates DB connection string based on ENV vars and default vars. /// /// DB connection string public string GetConnectionString() { //Read the parameters for the connection string form env vars string dbHost = Environment.GetEnvironmentVariable("DATABASE_HOST"); string dbPort = Environment.GetEnvironmentVariable("DATABASE_PORT"); string dbName = Environment.GetEnvironmentVariable("DATABASE_NAME"); string dbUser = Environment.GetEnvironmentVariable("DATABASE_USER"); string dbPassword = Environment.GetEnvironmentVariable("DATABASE_PASSWORD"); //Check if any of the env vars were null and set the parameters for the connection string to default parameters of any of them were null if(dbHost == null || dbPort == null || dbName == null || dbUser == null || dbPassword == null) { throw new ArgumentNullException(); } //Return the created connection String return $"Host={dbHost}; Port={dbPort}; Username={dbUser}; Database={dbName}; Password={dbPassword}"; } } }