public static IServiceCollection AddConsulDiscovery(this IServiceCollection services, Uri address, Action <ConsulDiscoveryBuilder> action = null)
        {
            var builder = new ConsulDiscoveryBuilder(address);

            action?.Invoke(builder);

            if (builder.Address == null)
            {
                throw new ArgumentNullException(nameof(builder.Address));
            }
            if (builder.CacheRefreshInterval < 5)
            {
                throw new ArgumentOutOfRangeException(nameof(builder.CacheRefreshInterval), "Must be greater than or equal to 5");
            }

            services.AddSingleton <IServiceRegistrar>(provider => {
                return(new ConsulServiceRegistrar(ConsulClientFactory.Create(builder.Address)));
            });

            services.AddSingleton <IServiceDiscovery>(provider => {
                return(new ConsulServiceDiscovery(ConsulClientFactory.Create(builder.Address)));
            });

            services.AddSingleton(typeof(IServiceSelector), builder.ServiceSelectorType);

            services.AddSingleton <IServicePool>(provider => {
                var options = new ServicePoolOptions()
                {
                    CacheRefreshInterval = builder.CacheRefreshInterval
                };
                return(new ServicePool(provider.GetService <IServiceDiscovery>(), provider.GetService <IServiceSelector>(), options));
            });

            return(services);
        }
 public async Task DeregisterSelfAsync()
 {
     using (var consulClient = ConsulClientFactory.Create())
     {
         foreach (var serviceName in serviceIds.Keys)
         {
             await consulClient.Agent.ServiceDeregister(serviceIds[serviceName]);
         }
     }
 }
Пример #3
0
        public async Task <CatalogService[]> GetCatalogServicesAsync(string serviceName, string serviceSpace = null, string serviceTag = null)
        {
            var scopedServiceName = GetScopedServiceName(serviceName, serviceSpace);

            using (var consulClient = ConsulClientFactory.Create())
            {
                var queryResult = string.IsNullOrEmpty(serviceTag) ? await consulClient.Catalog.Service(scopedServiceName) : await consulClient.Catalog.Service(scopedServiceName, serviceTag);

                return(queryResult.Response);
            }
        }
Пример #4
0
        static void Register()
        {
            var consulClient = ConsulClientFactory.Create(new ConsulDiscoveryConfiguration()
            {
                Address = consulAddress
            });
            ConsulServiceRegistrar registrar = new ConsulServiceRegistrar(consulClient);
            var info = registrar.RegisterServiceAsync("testServiceName", "v1.0", "192.168.0.81", 8080).Result;

            registrar.DeregisterServiceAsync(info.Id).Wait();
        }
Пример #5
0
        public async Task Run(CancellationToken cancellationToken = default)
        {
            var consulClient = _consulClientFactory.Create(_consulAddress, _consulToken, _consulDatacenter);

            _logger.LogDebug($"Watching for unhealthy Vault services named '{_consulServiceName}'.");

            var writer = _channel.Writer;

            ulong index = 0;

            while (!cancellationToken.IsCancellationRequested)
            {
                var queryOptions = new QueryOptions
                {
                    Consistency = ConsistencyMode.Consistent,
                    WaitIndex   = index
                };

                _logger.LogTrace($"Watching for updates after version {index}.");
                var result = await consulClient.Health.Service(_consulServiceName, null, false, queryOptions, cancellationToken);

                if (result == null)
                {
                    continue;
                }

                var unsealedVaults = result.Response
                                     .Where(x => x.Checks.Any(c => c.CheckID.EndsWith(":vault-sealed-check") && c.Status.Equals(HealthStatus.Critical)))
                                     .ToList();
                var hasUnsealedVaults = unsealedVaults.Any();
                if (hasUnsealedVaults)
                {
                    foreach (var service in unsealedVaults.Select(x => x.Service))
                    {
                        var vault = new Vault(new UriBuilder("https", service.Address, service.Port).Uri);

                        _logger.LogInformation($"Vault '{vault}' has been detected as sealed.");

                        var vaultEvent = new UnsealedVaultEvent(vault);
                        await writer.WriteAsync(vaultEvent, cancellationToken);
                    }
                }

                index = result.LastIndex;
                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
            }
        }
        public async Task <string> GetSettingAsync(string key, string serviceSpace = null)
        {
            VallidateSettingKey(key);

            string scopedKey = GetScopedKey(key, serviceSpace);

            using (var consulClient = ConsulClientFactory.Create())
            {
                var result = await consulClient.KV.Get(scopedKey);

                if (result.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    return(Encoding.UTF8.GetString(result.Response.Value, 0, result.Response.Value.Length));
                }

                return(null);
            }
        }
        public async Task <TValue> GetJsonSettingAsync <TValue>(string key, string semicolonsJoinedPropertyNames, string serviceSpace = null)
        {
            VallidateSettingKey(key);

            string scopedKey = GetScopedKey(key, serviceSpace);

            using (var consulClient = ConsulClientFactory.Create())
            {
                var result = await consulClient.KV.Get(scopedKey);

                if (result.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var returnValue = JsonConfigProvider.GetValueFromJson <TValue>(result.Response.Value, semicolonsJoinedPropertyNames);

                    return(returnValue);
                }

                return(default);
        public async Task <bool> PutSettingAsync(string key, string value, string serviceSpace = null)
        {
            VallidateSettingKey(key);

            string scopedKey = GetScopedKey(key, serviceSpace);
            var    putPair   = new KVPair(scopedKey)
            {
                Value = Encoding.UTF8.GetBytes(value)
            };

            using (var consulClient = ConsulClientFactory.Create())
            {
                var result = await consulClient.KV.Put(putPair);

                if (result.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    return(result.Response);
                }

                return(false);
            }
        }
Пример #9
0
        static void RegisterAndGetServices()
        {
            var consulClient = ConsulClientFactory.Create(new ConsulDiscoveryConfiguration()
            {
                Address = consulAddress
            });
            ConsulServiceRegistrar registrar = new ConsulServiceRegistrar(consulClient);
            var info  = registrar.RegisterServiceAsync("testServiceName", "v1.0", "192.168.0.81", 8080).Result;
            var info2 = registrar.RegisterServiceAsync("testServiceName", "v1.1", "192.168.0.81", 8090).Result;
            var info3 = registrar.RegisterServiceAsync("testServiceName", "v1.0", "192.168.0.81", 10101).Result;

            ConsulServiceDiscovery discovery = new ConsulServiceDiscovery(consulClient, new ConsulDiscoveryConfiguration()
            {
                Address = consulAddress
            });

            var services = discovery.GetServicesAsync("testServiceName").Result;

            var services2 = discovery.GetServicesAsync("testServiceName", "v1.0").Result;

            var service = discovery.GetServiceAsync("testServiceName").Result;
        }
Пример #10
0
        public async Task RegisterSelfAsync(Action <Dictionary <string, string> > appendMetaAction = null)
        {
            var serviceDescription        = LocalServiceDescriptionProvider.Build();
            var serviceSchema             = serviceDescription.ServiceSchema ?? "http";
            var registeringServiceAddress = $"{serviceSchema}://{serviceDescription.Host}:{serviceDescription.Port}";
            var virtualDirectory          = serviceDescription.VirtualDirectory.Trim('/');
            var serviceMeta = new Dictionary <string, string>
            {
                { ServiceGovernanceConsts.ServiceSchema, serviceSchema }
            };

            if (appendMetaAction != null)
            {
                appendMetaAction.Invoke(serviceMeta);
            }

            if (!string.IsNullOrEmpty(virtualDirectory))
            {
                serviceMeta.Add(ServiceGovernanceConsts.ServiceVirtualDirectory, serviceDescription.VirtualDirectory);
                registeringServiceAddress = $"{registeringServiceAddress}/{serviceDescription.VirtualDirectory}";
            }

            var serviceCheck = new AgentServiceCheck
            {
                Interval = ServiceGovernanceConfig.ServiceCheckInterval,
                HTTP     = $"{registeringServiceAddress}/{serviceDescription.HealthCheckRoute.Trim('/') ?? string.Empty}",
                Timeout  = ServiceGovernanceConfig.ServiceCheckTimeout,
            };

            if (!IsDevelopmentEnvironment())
            {
                serviceCheck.DeregisterCriticalServiceAfter = ServiceGovernanceConfig.DeregisterCriticalServiceAfter;
            }

            var serviceNames = new List <string> {
                serviceDescription.ServiceName
            };

            if (serviceDescription.ServiceAliases != null && serviceDescription.ServiceAliases.Contains(","))
            {
                foreach (var serviceAlias in serviceDescription.ServiceAliases.Split(','))
                {
                    var trimmedAlias = serviceAlias.Trim();

                    if (!string.IsNullOrEmpty(trimmedAlias))
                    {
                        serviceNames.Add(trimmedAlias);
                    }
                }
            }

            using (var consulClient = ConsulClientFactory.Create())
            {
                foreach (var serviceName in serviceNames)
                {
                    var serviceRegistration = new AgentServiceRegistration
                    {
                        Checks  = new[] { serviceCheck },
                        ID      = Guid.NewGuid().ToString(),
                        Address = serviceDescription.Host,
                        Port    = serviceDescription.Port == 0 ? 80 : serviceDescription.Port,
                        Meta    = serviceMeta,
                    };

                    if (string.IsNullOrEmpty(serviceDescription.ServiceSpace))
                    {
                        serviceRegistration.Name = serviceName;
                        serviceRegistration.Tags = new[] { $"urlprefix-/{serviceRegistration.Name}" };
                    }
                    else
                    {
                        serviceRegistration.Name = $"{serviceDescription.ServiceSpace}.{serviceName}";
                        serviceRegistration.Tags = new[] { serviceDescription.ServiceSpace, $"urlprefix-/{serviceRegistration.Name}" };
                    }

                    var existingServices = (await consulClient.Catalog.Service(serviceRegistration.Name)).Response;

                    foreach (var service in existingServices)
                    {
                        var registeredServiceAddress = service.GetRegisteredServiceAddress();
                        if (registeredServiceAddress == registeringServiceAddress)
                        {
                            await consulClient.Agent.ServiceDeregister(service.ServiceID);
                        }
                    }

                    var result = await consulClient.Agent.ServiceRegister(serviceRegistration);

                    if (result.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        serviceIds.Add(serviceRegistration.Name, serviceRegistration.ID);
                    }
                }
            }
        }