Example #1
0
        public static IApplicationBuilder UseDefaultForApi(
            this IApplicationBuilder app,
            StartupOptions options)
        {
            if (options.ApplicationContainer == null)
            {
                throw new ArgumentNullException(nameof(options.ApplicationContainer));
            }

            if (options.ServiceProvider == null)
            {
                throw new ArgumentNullException(nameof(options.ServiceProvider));
            }

            if (options.HostingEnvironment == null)
            {
                throw new ArgumentNullException(nameof(options.HostingEnvironment));
            }

            if (options.ApplicationLifetime == null)
            {
                throw new ArgumentNullException(nameof(options.ApplicationLifetime));
            }

            if (options.LoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(options.LoggerFactory));
            }

            if (string.IsNullOrWhiteSpace(options.Server.ServerName))
            {
                options.Server.ServerName = "Vlaamse overheid";
            }

            if (string.IsNullOrWhiteSpace(options.Server.PoweredByName))
            {
                options.Server.PoweredByName = "Vlaamse overheid - Basisregisters Vlaanderen";
            }

            if (options.Api.VersionProvider == null)
            {
                throw new ArgumentNullException(nameof(options.Api.VersionProvider));
            }

            if (options.Api.Info == null)
            {
                throw new ArgumentNullException(nameof(options.Api.Info));
            }

            if (options.HostingEnvironment.IsDevelopment())
            {
                app
                .UseDeveloperExceptionPage()
                .UseDatabaseErrorPage()
                .UseBrowserLink();
            }

            app.UseCors(policyName: StartupHelpers.AllowSpecificOrigin);
            options.MiddlewareHooks.AfterCors?.Invoke(app);

            app.UseApiExceptionHandler(options.LoggerFactory, StartupHelpers.AllowSpecificOrigin);
            options.MiddlewareHooks.AfterApiExceptionHandler?.Invoke(app);

            app
            .UseMiddleware <EnableRequestRewindMiddleware>()

            // https://github.com/serilog/serilog-aspnetcore/issues/59
            .UseMiddleware <AddCorrelationIdToResponseMiddleware>()
            .UseMiddleware <AddCorrelationIdMiddleware>()
            .UseMiddleware <AddCorrelationIdToLogContextMiddleware>()

            .UseMiddleware <AddHttpSecurityHeadersMiddleware>(options.Server.ServerName, options.Server.PoweredByName)

            .UseMiddleware <AddRemoteIpAddressMiddleware>()

            .UseMiddleware <AddVersionHeaderMiddleware>();
            options.MiddlewareHooks.AfterMiddleware?.Invoke(app);

            app
            .UseMiddleware <DefaultResponseCompressionQualityMiddleware>(new Dictionary <string, double>
            {
                { "br", 1.0 },
                { "gzip", 0.9 }
            })
            .UseResponseCompression();
            options.MiddlewareHooks.AfterResponseCompression?.Invoke(app);

            app.UseSwaggerDocumentation(options.Api.VersionProvider, options.Api.Info);
            options.MiddlewareHooks.AfterSwagger?.Invoke(app);

            app.UseMvc();
            options.MiddlewareHooks.AfterMvc?.Invoke(app);

            StartupHelpers.RegisterApplicationLifetimeHandling(
                options.ApplicationContainer,
                options.ApplicationLifetime,
                options.ServiceProvider.GetService <TraceAgent>());

            return(app);
        }
Example #2
0
        public static IApplicationBuilder UseDefaultForApi(
            this IApplicationBuilder app,
            StartupUseOptions options)
        {
            if (options.Common.ApplicationContainer == null)
            {
                throw new ArgumentNullException(nameof(options.Common.ApplicationContainer));
            }

            if (options.Common.ServiceProvider == null)
            {
                throw new ArgumentNullException(nameof(options.Common.ServiceProvider));
            }

            if (options.Common.HostingEnvironment == null)
            {
                throw new ArgumentNullException(nameof(options.Common.HostingEnvironment));
            }

            if (options.Common.ApplicationLifetime == null)
            {
                throw new ArgumentNullException(nameof(options.Common.ApplicationLifetime));
            }

            if (options.Common.LoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(options.Common.LoggerFactory));
            }

            if (string.IsNullOrWhiteSpace(options.Server.ServerName))
            {
                options.Server.ServerName = "Vlaamse overheid";
            }

            if (string.IsNullOrWhiteSpace(options.Server.PoweredByName))
            {
                options.Server.PoweredByName = "Vlaamse overheid - Basisregisters Vlaanderen";
            }

            if (options.Api.VersionProvider == null)
            {
                throw new ArgumentNullException(nameof(options.Api.VersionProvider));
            }

            GlobalStringLocalizer.Instance = new GlobalStringLocalizer(app.ApplicationServices.GetRequiredService <IServiceProvider>());

            if (options.Common.HostingEnvironment.IsDevelopment())
            {
                app
                .UseDeveloperExceptionPage()
                .UseDatabaseErrorPage()
                .UseBrowserLink();
            }

            app.UseCors(policyName: options.Api.DefaultCorsPolicy);
            options.MiddlewareHooks.AfterCors?.Invoke(app);

            app.UseProblemDetails();
            options.MiddlewareHooks.AfterProblemDetails?.Invoke(app);

            app.UseApiExceptionHandler(
                options.Api.DefaultCorsPolicy,
                options);
            options.MiddlewareHooks.AfterApiExceptionHandler?.Invoke(app);

            app
            .UseMiddleware <EnableRequestRewindMiddleware>()

            // https://github.com/serilog/serilog-aspnetcore/issues/59
            .UseMiddleware <AddCorrelationIdToResponseMiddleware>()
            .UseMiddleware <AddCorrelationIdMiddleware>()
            .UseMiddleware <AddCorrelationIdToLogContextMiddleware>()

            .UseMiddleware <AddHttpSecurityHeadersMiddleware>(
                options.Server.ServerName,
                options.Server.PoweredByName,
                options.Server.FrameOptionsDirective)

            .UseMiddleware <AddRemoteIpAddressMiddleware>(options.Api.RemoteIpAddressClaimName)

            .UseMiddleware <AddVersionHeaderMiddleware>(options.Server.VersionHeaderName);
            options.MiddlewareHooks.AfterMiddleware?.Invoke(app);

            app
            .UseMiddleware <DefaultResponseCompressionQualityMiddleware>(new Dictionary <string, double>
            {
                { "br", 1.0 },
                { "gzip", 0.9 }
            })
            .UseResponseCompression();
            options.MiddlewareHooks.AfterResponseCompression?.Invoke(app);

            var healthCheckOptions = new HealthCheckOptions
            {
                AllowCachingResponses = false,

                ResultStatusCodes =
                {
                    [HealthStatus.Healthy]   = StatusCodes.Status200OK,
                    [HealthStatus.Degraded]  = StatusCodes.Status200OK,
                    [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
                },

                ResponseWriter = (httpContext, healthReport) =>
                {
                    httpContext.Response.ContentType = "application/json";

                    var json = new JObject(
                        new JProperty("status", healthReport.Status.ToString()),
                        new JProperty("totalDuration", healthReport.TotalDuration.ToString()),
                        new JProperty("results", new JObject(healthReport.Entries.Select(pair =>
                                                                                         new JProperty(pair.Key, new JObject(
                                                                                                           new JProperty("status", pair.Value.Status.ToString()),
                                                                                                           new JProperty("duration", pair.Value.Duration),
                                                                                                           new JProperty("description", pair.Value.Description),
                                                                                                           new JProperty("exception", pair.Value.Exception?.Message),
                                                                                                           new JProperty("data", new JObject(pair.Value.Data.Select(
                                                                                                                                                 p => new JProperty(p.Key, p.Value))))))))));

                    return(httpContext.Response.WriteAsync(json.ToString(Formatting.Indented)));
                }
            };

            app.UseHealthChecks("/health", options.MiddlewareHooks.HealthChecks ?? healthCheckOptions);
            options.MiddlewareHooks.AfterHealthChecks?.Invoke(app);

            var requestLocalizationOptions = options
                                             .Common
                                             .ServiceProvider
                                             .GetRequiredService <IOptions <RequestLocalizationOptions> >()
                                             .Value;

            app.UseRequestLocalization(requestLocalizationOptions);
            options.MiddlewareHooks.AfterRequestLocalization?.Invoke(app);

            app.UseSwaggerDocumentation(new SwaggerDocumentationOptions
            {
                ApiVersionDescriptionProvider = options.Api.VersionProvider,
                DocumentTitleFunc             = options.Api.Info,
                DocumentDescriptionFunc       = options.Api.Description,
                ApplicationNameFunc           = options.Api.ApplicationName,
                HeaderTitleFunc = options.Api.HeaderTitle,
                HeaderLinkFunc  = options.Api.HeaderLink,
                HeadContentFunc = options.Api.HeadContent,
                FooterVersion   = options.Api.FooterVersion,
                CSharpClient    =
                {
                    ClassName = options.Api.CSharpClientOptions.ClassName,
                    Namespace = options.Api.CSharpClientOptions.Namespace
                },
                TypeScriptClient =
                {
                    ClassName = options.Api.TypeScriptClientOptions.ClassName
                }
            });
            options.MiddlewareHooks.AfterSwagger?.Invoke(app);

            app.UseMvc();
            options.MiddlewareHooks.AfterMvc?.Invoke(app);

            StartupHelpers.RegisterApplicationLifetimeHandling(
                options.Common.ApplicationContainer,
                options.Common.ApplicationLifetime,
                options.Common.ServiceProvider.GetService <TraceAgent>());

            return(app);
        }
Example #3
0
        public static IApplicationBuilder UseDataDog <T>(
            this IApplicationBuilder app,
            DataDogOptions options)
        {
            if (options.Common.ServiceProvider == null)
            {
                throw new ArgumentNullException(nameof(options.Common.ServiceProvider));
            }

            if (options.Common.LoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(options.Common.LoggerFactory));
            }

            if (options.Toggles.Enable == null)
            {
                throw new ArgumentNullException(nameof(options.Toggles.Enable));
            }

            if (options.Toggles.Debug == null)
            {
                throw new ArgumentNullException(nameof(options.Toggles.Debug));
            }

            if (string.IsNullOrWhiteSpace(options.Tracing.ServiceName))
            {
                throw new ArgumentNullException(nameof(options.Tracing.ServiceName));
            }

            if (string.IsNullOrWhiteSpace(options.Tracing.TraceIdHeaderName))
            {
                options.Tracing.TraceIdHeaderName = DataDogOptions.DefaultTraceIdHeaderName;
            }

            if (string.IsNullOrWhiteSpace(options.Tracing.ParentSpanIdHeaderName))
            {
                options.Tracing.ParentSpanIdHeaderName = DataDogOptions.DefaultParentSpanIdHeaderName;
            }

            if (options.Toggles.Enable.FeatureEnabled)
            {
                if (options.Toggles.Debug.FeatureEnabled)
                {
                    StartupHelpers.SetupSourceListener(options.Common.ServiceProvider.GetRequiredService <TraceSource>());
                }

                var traceSourceFactory = options.Common.ServiceProvider.GetRequiredService <Func <TraceSourceArguments, TraceSource> >();
                var logger             = options.Common.LoggerFactory.CreateLogger <T>();

                app.UseDataDogTracing(new TraceOptions
                {
                    TraceSource = request =>
                    {
                        var traceId = request.ExtractTraceIdFromHeader(
                            options.Tracing.TraceIdHeaderName,
                            options.Tracing.TraceIdGenerator,
                            logger);

                        var traceParentSpanId = request.ExtractTraceParentSpanIdFromHeader(
                            options.Tracing.ParentSpanIdHeaderName,
                            logger);

                        return(traceParentSpanId.HasValue
                            ? traceSourceFactory(new TraceSourceArguments(traceId, traceParentSpanId.Value))
                            : traceSourceFactory(new TraceSourceArguments(traceId)));
                    },
                    ServiceName      = options.Tracing.ServiceName,
                    ShouldTracePath  = options.Tracing.ShouldTracePath ?? (pathToCheck => pathToCheck != "/"),
                    AnalyticsEnabled = options.Tracing.AnalyticsEnabled
                });
            }

            return(app);
        }