public static IServiceCollection AddServiceDiscovery(this IServiceCollection services, IConfiguration serviceOptionsConfiguration) { services.AddOptions(); // setup options services.Configure <ServiceDiscoveryOptions>(serviceOptionsConfiguration); // register consul client services.AddSingleton <IConsulClient>(p => new ConsulClient(cfg => { var options = p.GetRequiredService <IOptions <ServiceDiscoveryOptions> >().Value; var serviceConfiguration = ServiceDiscoveryEnvFactory.Get(options); if (!string.IsNullOrEmpty(serviceConfiguration.Consul.HttpEndpoint)) { // if not configured, the client will use the default value "127.0.0.1:8500" cfg.Address = new Uri(serviceConfiguration.Consul.HttpEndpoint); } })); // register dns lookup services.AddSingleton <IDnsQuery>(p => { var options = p.GetRequiredService <IOptions <ServiceDiscoveryOptions> >().Value; var serviceConfiguration = ServiceDiscoveryEnvFactory.Get(options); var client = new LookupClient(IPAddress.Parse("127.0.0.1"), 8600); if (serviceConfiguration.Consul.DnsEndpoint != null) { client = new LookupClient(serviceConfiguration.Consul.DnsEndpoint.ToIPEndPoint()); } client.EnableAuditTrail = false; client.UseCache = true; client.MinimumCacheTimeout = TimeSpan.FromSeconds(1); return(client); }); return(services); }
public static IApplicationBuilder UseConsulRegisterService(this IApplicationBuilder app) { var appLife = app.ApplicationServices.GetRequiredService <IApplicationLifetime>() ?? throw new ArgumentException("Missing dependency", nameof(IApplicationLifetime)); var options = app.ApplicationServices.GetRequiredService <IOptions <ServiceDiscoveryOptions> >() ?? throw new ArgumentException("Missing dependency", nameof(IOptions <ServiceDiscoveryOptions>)); var serviceOptions = ServiceDiscoveryEnvFactory.Get(options.Value); var consul = app.ApplicationServices.GetRequiredService <IConsulClient>() ?? throw new ArgumentException("Missing dependency", nameof(IConsulClient)); var loggerFactory = app.ApplicationServices.GetRequiredService <ILoggerFactory>(); var logger = loggerFactory.CreateLogger("ServiceDiscoveryBuilder"); if (string.IsNullOrEmpty(serviceOptions.ServiceName)) { throw new ArgumentException("Service Name must be configured", nameof(serviceOptions.ServiceName)); } IEnumerable <Uri> addresses = null; if (serviceOptions.Endpoints != null && serviceOptions.Endpoints.Length > 0) { logger.LogInformation($"Using {serviceOptions.Endpoints.Length} configured endpoints for service registration."); addresses = serviceOptions.Endpoints.Select(p => new Uri(p)); } else { logger.LogInformation($"Trying to use server.Features to figure out the service endpoints for service registration."); var features = app.Properties["server.Features"] as FeatureCollection; addresses = features.Get <IServerAddressesFeature>() .Addresses .Select(p => new Uri(p)).ToArray(); } logger.LogInformation($"Found {addresses.Count()} endpoints: {string.Join(",", addresses.Select(p => p.OriginalString))}."); foreach (var address in addresses) { var serviceId = $"{serviceOptions.ServiceName}_{address.Host}:{address.Port}"; logger.LogInformation($"Registering service {serviceId} for address {address}."); var serviceChecks = new List <AgentServiceCheck>(); if (!string.IsNullOrEmpty(serviceOptions.HealthCheckTemplate)) { var healthCheckUri = new Uri(address, serviceOptions.HealthCheckTemplate).OriginalString; serviceChecks.Add(new AgentServiceCheck() { Status = HealthStatus.Passing, DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1), Interval = TimeSpan.FromSeconds(5), HTTP = healthCheckUri }); logger.LogInformation($"Adding healthcheck for service {serviceId}, checking {healthCheckUri}."); } var registration = new AgentServiceRegistration() { Checks = serviceChecks.ToArray(), Address = address.Host, ID = serviceId, Name = serviceOptions.ServiceName, Port = address.Port }; consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult(); appLife.ApplicationStopping.Register(() => { consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult(); }); } return(app); }