Esempio n. 1
0
        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);
        }