/// <summary> /// Constructor /// </summary> /// <param name="logger">Logger</param> /// <param name="options">Repository configuration options</param> public EtcdConfigurationRepository(ILogger <EtcdConfigurationRepository <TModel, TKey> > logger, EtcdConfigurationRepositoryOptions options) { _logger = logger; //Initialise serializer settings _jsonSerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, //Use custom serializer to ensure 'id' and 'version' properties don't get written to etcd ContractResolver = new ShouldSerializeContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }, NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None, SerializationBinder = new DefaultSerializationBinder(), }; //Create an initialisation task to create etcd client and initialise the watcher _initTask = CreateClient(options) .ContinueWith(async result => { if (result.IsFaulted) { throw result.Exception; } await Initialise(result.Result); _etcdClient = result.Result; }).Unwrap(); //Setup ready task to complete when initialisation is complete and initial data is loaded _readyTask = Task.WhenAll(_initTask, _dataLoaded.Task); }
/// <summary> /// Initialise etcd client /// </summary> /// <param name="options"></param> private async Task <EtcdClient> CreateClient(EtcdConfigurationRepositoryOptions options) { EtcdClient etcdClient = null; var lookup = new LookupClient(); if (options.UseEtcdClientDiscovery) { var dnsHostName = string.IsNullOrEmpty(options.DnsHostOverride) ? $"_etcd-client${(options.UseTLS ? "-ssl" : "")}.${options.EtcdClientDiscoveryDomain}" : options.DnsHostOverride; _logger.LogInformation("Attempting service discovery using hostname {dnsHostName}", dnsHostName); var dnsResponse = await lookup.QueryAsync(dnsHostName, QueryType.SRV); if (dnsResponse.Answers.Count > 0) { foreach (var srvRecord in dnsResponse.Answers.SrvRecords()) { _logger.LogInformation($"Connecting to etcd host {srvRecord.Target} using port {options.PortOverride ?? srvRecord.Port}."); var tmpEtcdClient = new EtcdClient(srvRecord.Target, options.PortOverride ?? srvRecord.Port, options.Username, options.Password); try { await tmpEtcdClient.StatusASync(new Etcdserverpb.StatusRequest()); etcdClient = tmpEtcdClient; break; } catch (Exception ex) { _logger.LogWarning(ex, "Failed to connect to etcd cluster."); tmpEtcdClient.Dispose(); } } } if (etcdClient == null) { if (!options.UseTLS) //Try again with TLS { _logger.LogInformation("Retrying discovery etcd cluster using TLS."); options.UseTLS = true; etcdClient = await CreateClient(options); } else { throw new InvalidOperationException("Unable to connect to a etcd cluster because service discovery operations failed."); } } } else if (!string.IsNullOrEmpty(options.DnsHostOverride)) { _logger.LogInformation($"Connecting to etcd host {options.DnsHostOverride} using port {options.PortOverride ?? 2379}."); etcdClient = new EtcdClient(options.DnsHostOverride, options.PortOverride ?? 2379, options.Username, options.Password); } else { throw new ArgumentException("Must specify 'DnsHostOverride option' if 'UseEtcdDiscovery' option is set to false."); } return(etcdClient); }