예제 #1
0
        private static IFixerBuilder AddServiceClient <T>(this IFixerBuilder builder, string serviceName,
                                                          RestEaseOptions options, Action <IFixerBuilder> registerFabio)
            where T : class
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            var clientName = typeof(T).ToString();

            switch (options.LoadBalancer?.ToLowerInvariant())
            {
            case "consul":
                builder.AddConsulHttpClient(clientName, serviceName);
                break;

            case "fabio":
                builder.AddFabioHttpClient(clientName, serviceName);
                break;

            default:
                ConfigureDefaultClient(builder.Services, clientName, serviceName, options);
                break;
            }

            ConfigureForwarder <T>(builder.Services, clientName);

            registerFabio(builder);

            return(builder);
        }
        private static IFixerBuilder AddFabio(this IFixerBuilder builder, FabioOptions fabioOptions,
                                              HttpClientOptions httpClientOptions, Action <IFixerBuilder> registerConsul)
        {
            registerConsul(builder);
            builder.Services.AddSingleton(fabioOptions);

            if (!fabioOptions.Enabled || !builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            if (httpClientOptions.Type?.ToLowerInvariant() == "fabio")
            {
                builder.Services.AddTransient <FabioMessageHandler>();
                builder.Services.AddHttpClient <IFabioHttpClient, FabioHttpClient>()
                .AddHttpMessageHandler <FabioMessageHandler>();
                builder.Services.AddHttpClient <IHttpClient, FabioHttpClient>()
                .AddHttpMessageHandler <FabioMessageHandler>();
            }

            using (var serviceProvider = builder.Services.BuildServiceProvider())
            {
                var registration = serviceProvider.GetService <AgentServiceRegistration>();
                registration.Tags = GetFabioTags(registration.Name, fabioOptions.Service);
                builder.Services.UpdateConsulRegistration(registration);
            }

            return(builder);
        }
예제 #3
0
        public static IFixerBuilder AddWebApi(this IFixerBuilder builder, string sectionName = SectionName)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            builder.Services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            builder.Services.AddSingleton(new WebApiEndpointDefinitions());
            builder.Services.AddRouting()
            .AddLogging()
            .AddMvcCore()
            .AddJsonFormatters()
            .AddDataAnnotations()
            .AddApiExplorer()
            .AddDefaultJsonOptions()
            .AddAuthorization();

            builder.Services.Scan(s =>
                                  s.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
                                  .AddClasses(c => c.AssignableTo(typeof(IRequestHandler <,>)))
                                  .AsImplementedInterfaces()
                                  .WithTransientLifetime());

            builder.Services.AddTransient <IRequestDispatcher, RequestDispatcher>();

            return(builder);
        }
예제 #4
0
        public static IFixerBuilder AddHttpClient(this IFixerBuilder builder, string sectionName = SectionName)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            var options = builder.GetOptions <HttpClientOptions>(sectionName);

            builder.Services.AddSingleton(options);
            builder.Services.AddHttpClient <IHttpClient, FixerHttpClient>();

            return(builder);
        }
예제 #5
0
        public static IFixerBuilder AddRedis(this IFixerBuilder builder, RedisOptions options)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            builder.Services.AddDistributedRedisCache(o =>
            {
                o.Configuration = options.ConnectionString;
                o.InstanceName  = options.Instance;
            });

            return(builder);
        }
예제 #6
0
        public static IFixerBuilder AddConsul(this IFixerBuilder builder, ConsulOptions options,
                                              HttpClientOptions httpClientOptions)
        {
            builder.Services.AddSingleton(options);
            if (!options.Enabled || !builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            if (httpClientOptions.Type?.ToLowerInvariant() == "consul")
            {
                builder.Services.AddTransient <ConsulServiceDiscoveryMessageHandler>();
                builder.Services.AddHttpClient <IConsulHttpClient, ConsulHttpClient>()
                .AddHttpMessageHandler <ConsulServiceDiscoveryMessageHandler>();
                builder.Services.AddHttpClient <IHttpClient, ConsulHttpClient>()
                .AddHttpMessageHandler <ConsulServiceDiscoveryMessageHandler>();
            }

            builder.Services.AddTransient <IConsulServicesRegistry, ConsulServicesRegistry>();
            builder.Services.AddSingleton <IConsulClient>(c => new ConsulClient(cfg =>
            {
                if (!string.IsNullOrEmpty(options.Url))
                {
                    cfg.Address = new Uri(options.Url);
                }
            }));

            var registration = builder.CreateConsulAgentRegistration(options);

            if (registration is null)
            {
                return(builder);
            }

            builder.Services.AddSingleton(registration);
            builder.AddBuildAction(sp =>
            {
                var consulRegistration = sp.GetService <AgentServiceRegistration>();
                var client             = sp.GetService <IConsulClient>();

                client.Agent.ServiceRegister(consulRegistration);
            });

            return(builder);
        }
예제 #7
0
        public static IFixerBuilder AddJaeger(this IFixerBuilder builder, JaegerOptions options)
        {
            builder.Services.AddSingleton(options);
            if (!options.Enabled)
            {
                var defaultTracer = ConveyDefaultTracer.Create();
                builder.Services.AddSingleton(defaultTracer);
                return(builder);
            }

            if (!builder.TryRegister(RegistryName) || _initialized)
            {
                return(builder);
            }

            _initialized = true;
            builder.Services.AddSingleton <ITracer>(sp =>
            {
                var loggerFactory = sp.GetRequiredService <ILoggerFactory>();

                var reporter = new RemoteReporter.Builder()
                               .WithSender(new UdpSender(options.UdpHost, options.UdpPort, options.MaxPacketSize))
                               .WithLoggerFactory(loggerFactory)
                               .Build();

                var sampler = GetSampler(options);

                var tracer = new Tracer.Builder(options.ServiceName)
                             .WithLoggerFactory(loggerFactory)
                             .WithReporter(reporter)
                             .WithSampler(sampler)
                             .Build();

                GlobalTracer.Register(tracer);

                return(tracer);
            });

            return(builder);
        }
예제 #8
0
        public static IFixerBuilder AddMongo(this IFixerBuilder builder, MongoDbOptions mongoOptions,
                                             IMongoDbSeeder seeder = null)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            builder.Services.AddSingleton(mongoOptions);

            builder.Services.AddSingleton <IMongoClient>(sp =>
            {
                var options = sp.GetService <MongoDbOptions>();
                return(new MongoClient(options.ConnectionString));
            });

            builder.Services.AddTransient(sp =>
            {
                var options = sp.GetService <MongoDbOptions>();
                var client  = sp.GetService <IMongoClient>();
                return(client.GetDatabase(options.Database));
            });

            builder.Services.AddTransient <IMongoDbInitializer, MongoDbInitializer>();
            builder.Services.AddTransient <IMongoSessionFactory, MongoSessionFactory>();

            if (seeder is null)
            {
                builder.Services.AddSingleton <IMongoDbSeeder, MongoDbSeeder>();
            }
            else
            {
                builder.Services.AddSingleton(seeder);
            }

            builder.AddInitializer <IMongoDbInitializer>();

            return(builder);
        }
예제 #9
0
        public static IFixerBuilder AddRabbitMq(this IFixerBuilder builder, string sectionName = SectionName)
        {
            var options = builder.GetOptions <RabbitMqOptions>(sectionName);

            builder.Services.AddSingleton(options);
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            builder.Services.AddSingleton <IContextProvider, ContextProvider>();
            builder.Services.AddSingleton <ICorrelationContextAccessor>(new CorrelationContextAccessor());
            builder.Services.AddSingleton <IMessagePropertiesAccessor>(new MessagePropertiesAccessor());
            builder.Services.AddSingleton <IConventionsBuilder, ConventionsBuilder>();
            builder.Services.AddSingleton <IConventionsProvider, ConventionsProvider>();
            builder.Services.AddSingleton <IConventionsRegistry, ConventionsRegistry>();
            builder.Services.AddSingleton <IRabbitMqSerializer, NewtonsoftJsonRabbitMqSerializer>();
            builder.Services.AddSingleton <IRabbitMqClient, RabbitMqClient>();
            builder.Services.AddSingleton <IBusPublisher, RabbitMqPublisher>();
            builder.Services.AddSingleton <IBusSubscriber, RabbitMqSubscriber>();
            if (options.MessageProcessor?.Enabled == true)
            {
                builder.Services.AddSingleton <IRabbitMqMiddleware, UniqueMessagesMiddleware>();
                builder.Services.AddSingleton <IUniqueMessagesMiddleware, UniqueMessagesMiddleware>();
                switch (options.MessageProcessor.Type?.ToLowerInvariant())
                {
                default:
                    builder.Services.AddMemoryCache();
                    builder.Services.AddSingleton <IMessageProcessor, InMemoryMessageProcessor>();
                    break;
                }
            }
            else
            {
                builder.Services.AddSingleton <IMessageProcessor, EmptyMessageProcessor>();
            }

            builder.Services.AddSingleton(sp =>
            {
                var connectionFactory = new ConnectionFactory
                {
                    HostName    = options.HostNames?.FirstOrDefault(),
                    Port        = options.Port,
                    VirtualHost = options.VirtualHost,
                    UserName    = options.Username,
                    Password    = options.Password,
                    RequestedConnectionTimeout = options.RequestedConnectionTimeout,
                    SocketReadTimeout          = options.SocketReadTimeout,
                    SocketWriteTimeout         = options.SocketWriteTimeout,
                    RequestedChannelMax        = options.RequestedChannelMax,
                    RequestedFrameMax          = options.RequestedFrameMax,
                    RequestedHeartbeat         = options.RequestedHeartbeat,
                    UseBackgroundThreadsForIO  = options.UseBackgroundThreadsForIO,
                    DispatchConsumersAsync     = true,
                    Ssl = options.Ssl is null
                        ? new SslOption()
                        : new SslOption(options.Ssl.ServerName, options.Ssl.CertificatePath, options.Ssl.Enabled)
                };

                var connection = connectionFactory.CreateConnection(options.ConnectionName);
                if (options.Exchange is null || !options.Exchange.Declare)
                {
                    return(connection);
                }

                using (var channel = connection.CreateModel())
                {
                    if (options.Logger?.Enabled == true)
                    {
                        var logger = sp.GetService <ILogger <IConnection> >();
                        logger.LogInformation($"Declaring an exchange: '{options.Exchange.Name}', type: '{options.Exchange.Type}'.");
                    }

                    channel.ExchangeDeclare(options.Exchange.Name, options.Exchange.Type, options.Exchange.Durable,
                                            options.Exchange.AutoDelete);
                    channel.Close();
                }

                return(connection);
            });

            return(builder);
        }
예제 #10
0
        public static IFixerBuilder AddMetrics(this IFixerBuilder builder, MetricsOptions options)
        {
            builder.Services.AddSingleton(options);
            if (!builder.TryRegister(RegistryName) || !options.Enabled || _initialized)
            {
                return(builder);
            }

            _initialized = true;
            var metricsBuilder = new MetricsBuilder().Configuration.Configure(cfg =>
            {
                var tags = options.Tags;
                if (tags == null)
                {
                    return;
                }

                tags.TryGetValue("app", out var app);
                tags.TryGetValue("env", out var env);
                tags.TryGetValue("server", out var server);
                cfg.AddAppTag(string.IsNullOrWhiteSpace(app) ? null : app);
                cfg.AddEnvTag(string.IsNullOrWhiteSpace(env) ? null : env);
                cfg.AddServerTag(string.IsNullOrWhiteSpace(server) ? null : server);
                foreach (var tag in tags)
                {
                    if (!cfg.GlobalTags.ContainsKey(tag.Key))
                    {
                        cfg.GlobalTags.Add(tag.Key, tag.Value);
                    }
                }
            });

            if (options.InfluxEnabled)
            {
                metricsBuilder.Report.ToInfluxDb(o =>
                {
                    o.InfluxDb.Database = options.Database;
                    o.InfluxDb.BaseUri  = new Uri(options.InfluxUrl);
                    o.InfluxDb.CreateDataBaseIfNotExists = true;
                    o.FlushInterval = TimeSpan.FromSeconds(options.Interval);
                });
            }

            var metrics = metricsBuilder.Build();
            var metricsWebHostOptions = GetMetricsWebHostOptions(options);

            using (var serviceProvider = builder.Services.BuildServiceProvider())
            {
                var configuration = serviceProvider.GetService <IConfiguration>();
                builder.Services.AddHealth();
                builder.Services.AddHealthEndpoints(configuration);
                builder.Services.AddMetricsTrackingMiddleware(configuration);
                builder.Services.AddMetricsEndpoints(configuration);
                builder.Services.AddSingleton <IStartupFilter>(new DefaultMetricsEndpointsStartupFilter());
                builder.Services.AddSingleton <IStartupFilter>(new DefaultHealthEndpointsStartupFilter());
                builder.Services.AddSingleton <IStartupFilter>(new DefaultMetricsTrackingStartupFilter());
                builder.Services.AddMetricsReportingHostedService(metricsWebHostOptions.UnobservedTaskExceptionHandler);
                builder.Services.AddMetricsEndpoints(metricsWebHostOptions.EndpointOptions, configuration);
                builder.Services.AddMetricsTrackingMiddleware(metricsWebHostOptions.TrackingMiddlewareOptions,
                                                              configuration);
                builder.Services.AddMetrics(metrics);
            }

            return(builder);
        }