public void ShouldConnectAndObserveConnection()
        {
            var rabbitMqConnectionOptions = new RabbitMqConnectionOptions()
            {
                HostName = "localhost",
                Password = "******",
                Username = "******",
            };


            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Information()
                         .MinimumLevel.Override("Microsoft", LogEventLevel.Debug)
                         .WriteTo.Debug()
                         .CreateLogger();

            var loggerFactory = new LoggerFactory().AddSerilog(Log.Logger);

            var anabasisAppContext = new AnabasisAppContext("appName", "appGroup", new Version(1, 0));

            var connection = new RabbitMqConnection(rabbitMqConnectionOptions, anabasisAppContext, loggerFactory);

            var rabbitMqConnectionStatusMonitor = new RabbitMqConnectionStatusMonitor(connection, loggerFactory);

            Assert.AreEqual(true, rabbitMqConnectionStatusMonitor.IsConnected);
        }
Пример #2
0
        public ExceptionActionFilterAttribute(AnabasisAppContext appContext)
        {
            _defaultErrors = new Dictionary <Type, HttpStatusCode>
            {
                { typeof(ArgumentException), HttpStatusCode.InternalServerError },
                { typeof(ValidationException), HttpStatusCode.BadRequest },
                { typeof(JsonSerializationException), HttpStatusCode.BadRequest },
            };

            _appContext = appContext;
        }
        public static RabbitMqBus GetRabbitMqBus()
        {
            var rabbitMqConnectionOptions = new RabbitMqConnectionOptions()
            {
                HostName = "localhost",
                Password = "******",
                Username = "******",
            };
            var anabasisAppContext = new AnabasisAppContext("appName", "appGroup", new Version(1, 0));
            var loggerFactory      = new LoggerFactory();
            var defaultSerializer  = new DefaultSerializer();

            var rabbitMqBus = new RabbitMqBus(
                rabbitMqConnectionOptions,
                anabasisAppContext,
                defaultSerializer,
                loggerFactory
                );

            return(rabbitMqBus);
        }
        public RabbitMqBus(RabbitMqConnectionOptions rabbitMqConnectionOptions,
                           AnabasisAppContext appContext,
                           ISerializer serializer,
                           ILoggerFactory?loggerFactory = null,
                           IKillSwitch?killSwitch       = null,
                           RetryPolicy?retryPolicy      = null)
        {
            BusId = $"{nameof(RabbitMqBus)}_{Guid.NewGuid()}";

            _logger     = loggerFactory?.CreateLogger <RabbitMqBus>();
            _serializer = serializer;
            _defaultPublishConfirmTimeout = TimeSpan.FromSeconds(10);
            _existingSubscriptions        = new Dictionary <string, IRabbitMqSubscription>();
            _ensureExchangeCreated        = new List <string>();
            _rabbitMqConnectionOptions    = rabbitMqConnectionOptions;
            _killSwitch = killSwitch ?? new KillSwitch();
            _appContext = appContext;

            RabbitMqConnection      = new RabbitMqConnection(rabbitMqConnectionOptions, appContext, loggerFactory, retryPolicy);
            ConnectionStatusMonitor = new RabbitMqConnectionStatusMonitor(RabbitMqConnection, loggerFactory);
        }
 public RequestContextHeadersMiddleware(RequestDelegate next, AnabasisAppContext appContext)
 {
     _next            = next;
     _applicationName = appContext.ApplicationName;
 }
Пример #6
0
        public static IWebHostBuilder Create <THost>(
            int apiPort = 80,
            int memoryCheckTresholdInMB = 200,
            bool useCors           = false,
            ISerializer?serializer = null,
            Action <MvcOptions>?configureMvcBuilder         = null,
            Action <IMvcBuilder>?configureMvc               = null,
            Action <MvcNewtonsoftJsonOptions>?configureJson = null,
            Action <KestrelServerOptions>?configureKestrel  = null,
            Action <AnabasisAppContext, IApplicationBuilder>?configureApplicationBuilder = null,
            Action <AnabasisAppContext, IServiceCollection, IConfigurationRoot>?configureServiceCollection = null,
            Action <ConfigurationBuilder>?configureConfigurationBuilder = null,
            Action <LoggerConfiguration>?configureLogging = null)
        {
            var anabasisConfiguration = Configuration.GetConfigurations(configureConfigurationBuilder);

            var anabasisAppContext = new AnabasisAppContext(
                anabasisConfiguration.AppConfigurationOptions.ApplicationName,
                anabasisConfiguration.GroupConfigurationOptions.GroupName,
                anabasisConfiguration.AppConfigurationOptions.ApiVersion,
                anabasisConfiguration.AppConfigurationOptions.SentryDsn,
                anabasisConfiguration.AnabasisEnvironment,
                anabasisConfiguration.AppConfigurationOptions.DocUrl,
                apiPort,
                memoryCheckTresholdInMB,
                Environment.MachineName);

            var loggerConfiguration = new LoggerConfiguration();

            loggerConfiguration
            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
            .Enrich.FromLogContext()
            .WriteTo.Console();

            if (anabasisAppContext.UseSentry)
            {
                loggerConfiguration.WriteTo.Sentry(
                    dsn: anabasisAppContext.SentryDsn,
                    sampleRate: 1f,
                    debug: false);
            }

            configureLogging?.Invoke(loggerConfiguration);

            Log.Logger = loggerConfiguration.CreateLogger();

            if (null == configureKestrel)
            {
                configureKestrel = kestrelServerOptions => { kestrelServerOptions.AllowSynchronousIO = true; }
            }
            ;

            var webHostBuilder = WebHost.CreateDefaultBuilder()
                                 .UseKestrel(configureKestrel);

            webHostBuilder = webHostBuilder
                             .UseUrls("http://+:" + anabasisAppContext.ApiPort)
                             .UseEnvironment($"{anabasisAppContext.Environment}")
                             .UseSetting(WebHostDefaults.ApplicationKey, anabasisAppContext.ApplicationName)
                             .UseSetting(WebHostDefaults.StartupAssemblyKey, Assembly.GetExecutingAssembly().GetName().Name)
                             .UseSerilog()
                             .ConfigureServices((context, services) =>
            {
                ConfigureServices <THost>(services, useCors, anabasisAppContext, serializer, configureMvcBuilder, configureMvc, configureJson);

                configureServiceCollection?.Invoke(anabasisAppContext, services, anabasisConfiguration.ConfigurationRoot);
            })
                             .Configure((context, appBuilder) =>
            {
                ConfigureApplication(appBuilder, context.HostingEnvironment, anabasisAppContext, useCors);

                configureApplicationBuilder?.Invoke(anabasisAppContext, appBuilder);
            });

            return(webHostBuilder);
        }
Пример #7
0
        private static void ConfigureApplication(
            IApplicationBuilder appBuilder,
            IWebHostEnvironment webHostEnvironment,
            AnabasisAppContext appContext,
            bool useCors)
        {
            appBuilder.WithClientIPAddress();
            appBuilder.WithRequestContextHeaders();
            appBuilder.UseResponseCompression();
            appBuilder.UseResponseCaching();

            appBuilder.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

            appBuilder.UseRouting();

            appBuilder.UseSerilogRequestLogging();

            appBuilder.UseSwagger();


            if (webHostEnvironment.IsDevelopment())
            {
                appBuilder.UseSwaggerUI(c => c.SwaggerEndpoint($"/swagger/v{appContext.ApiVersion.Major}/swagger.json",
                                                               $"{appContext.Environment} v{appContext.ApiVersion.Major}"));
            }

            if (useCors)
            {
                appBuilder.UseCors("cors");
            }

            appBuilder.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();

                endpoints.MapHealthChecks("/health", new HealthCheckOptions()
                {
                    ResponseWriter = async(httpContext, healthReport) =>
                    {
                        var combinedHealthReport = healthReport;

                        var dynamicHealthCheckProvider = httpContext.RequestServices.GetService <IDynamicHealthCheckProvider>();

                        if (null != dynamicHealthCheckProvider)
                        {
                            var dynamicHealthCheckHealthReport = await dynamicHealthCheckProvider.CheckHealth(CancellationToken.None);

                            combinedHealthReport = healthReport.Combine(dynamicHealthCheckHealthReport);
                        }

                        httpContext.Response.StatusCode  = (int)(combinedHealthReport.Status == HealthStatus.Unhealthy ? HttpStatusCode.ServiceUnavailable : HttpStatusCode.OK);
                        httpContext.Response.ContentType = "application/json; charset=utf-8";

                        await httpContext.Response.WriteAsync(combinedHealthReport.ToJson());
                    }
                });
            });
        }
Пример #8
0
        private static void ConfigureServices <THost>(
            IServiceCollection services,
            bool useCors,
            AnabasisAppContext appContext,
            ISerializer?serializer = null,
            Action <MvcOptions>?configureMvcBuilder         = null,
            Action <IMvcBuilder>?configureMvc               = null,
            Action <MvcNewtonsoftJsonOptions>?configureJson = null)
        {
            services.AddOptions();

            const long MBytes = 1024L * 1024L;

            services.AddHealthChecks()
            .AddWorkingSetHealthCheck(appContext.MemoryCheckTresholdInMB * 3L * MBytes, "Working set", HealthStatus.Unhealthy);

            services.AddSingleton(serializer ?? new DefaultSerializer());

            services.AddHostedService <HealthCheckHostedService>();

            services.AddResponseCaching((options) =>
            {
                options.SizeLimit       = 10 * MBytes;
                options.MaximumBodySize = 5 * MBytes;
            });

            services.AddApiVersioning(apiVersioningOptions =>
            {
                apiVersioningOptions.ErrorResponses    = new ErrorResponseProvider();
                apiVersioningOptions.ReportApiVersions = true;
                apiVersioningOptions.AssumeDefaultVersionWhenUnspecified = true;
                apiVersioningOptions.ApiVersionReader  = new HeaderApiVersionReader(HttpHeaderConstants.HTTP_HEADER_API_VERSION);
                apiVersioningOptions.DefaultApiVersion = new ApiVersion(appContext.ApiVersion.Major, appContext.ApiVersion.Minor);
            });

            services
            .AddSingleton <IHttpContextAccessor, HttpContextAccessor>()
            .AddSingleton(appContext)
            .AddControllers(options =>
            {
                options.Filters.Add <RequiredParametersActionFilterAttribute>();
                options.Filters.Add <ModelValidationActionFilterAttribute>();
                options.Filters.Add <ExceptionActionFilterAttribute>();
                options.RespectBrowserAcceptHeader = true;
            })
            .AddNewtonsoftJson(options =>
            {
                var jsonSerializerSettings        = options.SerializerSettings;
                var defaultJsonSerializerSettings = Json.GetDefaultJsonSerializerSettings();

                jsonSerializerSettings.ReferenceLoopHandling = defaultJsonSerializerSettings.ReferenceLoopHandling;
                jsonSerializerSettings.NullValueHandling     = defaultJsonSerializerSettings.NullValueHandling;
                jsonSerializerSettings.DateTimeZoneHandling  = defaultJsonSerializerSettings.DateTimeZoneHandling;
                jsonSerializerSettings.Formatting            = defaultJsonSerializerSettings.Formatting;
                jsonSerializerSettings.DateFormatHandling    = defaultJsonSerializerSettings.DateFormatHandling;

                jsonSerializerSettings.Converters = defaultJsonSerializerSettings.Converters;

                jsonSerializerSettings.StringEscapeHandling = defaultJsonSerializerSettings.StringEscapeHandling;

                configureJson?.Invoke(options);

                Json.SetDefaultJsonSerializerSettings(jsonSerializerSettings);
            });

            services.Configure <ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = actionContext =>
                {
                    var error = actionContext.ModelState
                                .Where(errors => errors.Value.Errors.Count > 0)
                                .Select(_ => new ValidationProblemDetails(actionContext.ModelState))
                                .FirstOrDefault();

                    var actionName = actionContext.ActionDescriptor.GetActionName();

                    var docUrl = actionName == null ? null : DocUrlHelper.GetDocUrl(actionName, appContext.DocUrl);

                    var messages = actionContext.ModelState
                                   .Where(errors => errors.Value.Errors.Count > 0)
                                   .SelectMany(errors => errors.Value.Errors)
                                   .Select(errors => new UserErrorMessage(HttpStatusCode.BadRequest, errors.ErrorMessage, docUrl: docUrl))
                                   .ToArray();

                    var response = new ErrorResponseMessage(messages);

                    return(new ErrorResponseMessageActionResult(response, HttpStatusCode.BadRequest));
                };
            });

            services.AddResponseCompression(options =>
            {
                options.Providers.Add <GzipCompressionProvider>();
            });

            if (useCors)
            {
                services.AddCors(options =>
                {
                    options.AddPolicy(name: "cors",
                                      builder =>
                    {
                        builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader();
                    });
                });
            }

            services.AddSwaggerGen(swaggerGenOptions =>
            {
                swaggerGenOptions.DocInclusionPredicate((version, apiDesc) => !string.IsNullOrEmpty(apiDesc.HttpMethod));

                swaggerGenOptions.MapType <Guid>(() => new OpenApiSchema {
                    Type = "string", Format = "Guid"
                });
                swaggerGenOptions.CustomSchemaIds(type => type.Name);
                swaggerGenOptions.IgnoreObsoleteProperties();
                swaggerGenOptions.UseInlineDefinitionsForEnums();

                swaggerGenOptions.SwaggerDoc($"v{appContext.ApiVersion.Major}",
                                             new OpenApiInfo {
                    Title = appContext.ApplicationName, Version = $"v{appContext.ApiVersion.Major}"
                });
            });

            var mvcBuilder = services.AddMvc(mvcOptions =>
            {
                configureMvcBuilder?.Invoke(mvcOptions);
            });

            mvcBuilder.AddApplicationPart(typeof(THost).Assembly);

            configureMvc?.Invoke(mvcBuilder);
        }