예제 #1
0
파일: Startup.cs 프로젝트: happy-travel/edo
        public void ConfigureServices(IServiceCollection services)
        {
            var serializationSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting       = Formatting.None
            };

            JsonConvert.DefaultSettings = () => serializationSettings;

            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                BaseUrl = new Uri(EnvironmentVariableHelper.Get("Vault:Endpoint", Configuration)),
                Engine  = Configuration["Vault:Engine"],
                Role    = Configuration["Vault:Role"]
            });
            vaultClient.Login(EnvironmentVariableHelper.Get("Vault:Token", Configuration)).GetAwaiter().GetResult();

            services.AddResponseCompression()
            .AddCors()
            .AddLocalization()
            .AddMemoryCache()
            .AddMemoryFlow()
            .AddStackExchangeRedisCache(options =>
            {
                var host = EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration);
                options.ConfigurationOptions = new ConfigurationOptions
                {
                    EndPoints    = { new DnsEndPoint(host, 6379) },
                    AsyncTimeout = 15000,     // set to 15 seconds before we stop storing large objects in Redis
                };
            })
            .AddDoubleFlow()
            .AddCacheFlowJsonSerialization()
            .AddTracing(Configuration, options =>
            {
                options.ServiceName = $"{HostingEnvironment.ApplicationName}-{HostingEnvironment.EnvironmentName}";
                options.JaegerHost  = HostingEnvironment.IsLocal()
                        ? Configuration.GetValue <string>("Jaeger:AgentHost")
                        : Configuration.GetValue <string>(Configuration.GetValue <string>("Jaeger:AgentHost"));
                options.JaegerPort = HostingEnvironment.IsLocal()
                        ? Configuration.GetValue <int>("Jaeger:AgentPort")
                        : Configuration.GetValue <int>(Configuration.GetValue <string>("Jaeger:AgentPort"));
                options.RedisEndpoint = Configuration.GetValue <string>(Configuration.GetValue <string>("Redis:Endpoint"));
            })
            .AddUserEventLogging(Configuration, vaultClient);

            var(apiName, authorityUrl) = GetApiNameAndAuthority(Configuration, HostingEnvironment, vaultClient);

            services.ConfigureServiceOptions(Configuration, HostingEnvironment, vaultClient)
            .ConfigureHttpClients(Configuration, HostingEnvironment, vaultClient, authorityUrl)
            .ConfigureAuthentication(Configuration, HostingEnvironment, apiName, authorityUrl)
            .AddServices(HostingEnvironment, Configuration, vaultClient);

            services.AddHealthChecks()
            .AddDbContextCheck <EdoContext>()
            .AddRedis(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration))
            .AddCheck <ControllerResolveHealthCheck>(nameof(ControllerResolveHealthCheck));

            services.AddProblemDetailsErrorHandling();

            services.AddApiVersioning(options =>
            {
                options.AssumeDefaultVersionWhenUnspecified = false;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("agent", new OpenApiInfo {
                    Title = "Happytravel.com Edo API for an agent app", Version = "v1.0"
                });
                options.SwaggerDoc("admin", new OpenApiInfo {
                    Title = "Happytravel.com Edo API for an admin app", Version = "v1.0"
                });
                options.SwaggerDoc("property-owner", new OpenApiInfo {
                    Title = "Happytravel.com Edo API for property owners", Version = "v1.0"
                });
                options.SwaggerDoc("service", new OpenApiInfo {
                    Title = "Happytravel.com service Edo API", Version = "v1.0"
                });

                var xmlCommentsFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlCommentsFilePath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFileName);
                options.IncludeXmlComments(xmlCommentsFilePath);
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey
                });
                options.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id   = "Bearer"
                            },
                            Scheme = "oauth2",
                            Name   = "Bearer",
                            In     = ParameterLocation.Header,
                        },
                        Array.Empty <string>()
                    }
                });
                // Use fully qualified object names
                options.CustomSchemaIds(x => x.FullName);
            });
            services.AddSwaggerGenNewtonsoftSupport();

            services.AddNotificationCenter(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration));

            services.AddMvcCore(options =>
            {
                options.Conventions.Insert(0, new LocalizationConvention());
                options.Conventions.Add(new AuthorizeControllerModelConvention());
                options.Conventions.Add(new ApiExplorerGroupPerVersionConvention());
                options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipelineFilter)));
                options.Filters.Add(typeof(ModelValidationFilter));

                AddODataMediaTypes(options);
            })
            .AddAuthorization()
            .AddControllersAsServices()
            .AddMvcOptions(m => m.EnableEndpointRouting = true)
            .AddFormatterMappings()
            .AddNewtonsoftJson(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()))
            .AddApiExplorer()
            .AddCacheTagHelper()
            .AddDataAnnotations()
            .AddOData(opt => opt.Filter().Select().OrderBy().SetMaxTop(100));
        }