private async Task <string> GetConfigInner(string tenant, string dataId, string group, long timeoutMs) { group = ParamUtils.Null2DefaultGroup(group); ParamUtils.CheckKeyParam(dataId, group); ConfigResponse cr = new ConfigResponse(); cr.SetDataId(dataId); cr.SetTenant(tenant); cr.SetGroup(group); // 优先使用本地配置 string content = await FileLocalConfigInfoProcessor.GetFailoverAsync(_worker.GetAgentName(), dataId, group, tenant); if (content != null) { _logger?.LogWarning( "[{0}] [get-config] get failover ok, dataId={1}, group={2}, tenant={3}, config={4}", _worker.GetAgentName(), dataId, group, tenant, ContentUtils.TruncateContent(content)); cr.SetContent(content); _configFilterChainManager.DoFilter(null, cr); content = cr.GetContent(); return(content); } try { List <string> ct = await _worker.GetServerConfig(dataId, group, tenant, timeoutMs, false); cr.SetContent(ct[0]); _configFilterChainManager.DoFilter(null, cr); content = cr.GetContent(); return(content); } catch (NacosException ioe) { if (NacosException.NO_RIGHT == ioe.ErrorCode) { throw; } _logger?.LogWarning( "[{0}] [get-config] get from server error, dataId={1}, group={2}, tenant={3}, msg={4}", _worker.GetAgentName(), dataId, group, tenant, ioe.ErrorMsg); } _logger?.LogWarning( "[{0}] [get-config] get snapshot ok, dataId={1}, group={2}, tenant={3}, config={4}", _worker.GetAgentName(), dataId, group, tenant, ContentUtils.TruncateContent(content)); content = await FileLocalConfigInfoProcessor.GetSnapshotAync(_worker.GetAgentName(), dataId, group, tenant); cr.SetContent(content); _configFilterChainManager.DoFilter(null, cr); content = cr.GetContent(); return(content); }
private async Task CheckLocalConfig(string agentName, CacheData cacheData) { string dataId = cacheData.DataId; string group = cacheData.Group; string tenant = cacheData.Tenant; var path = FileLocalConfigInfoProcessor.GetFailoverFile(agentName, dataId, group, tenant); if (!cacheData.IsUseLocalConfig && path.Exists) { string content = await FileLocalConfigInfoProcessor.GetFailoverAsync(agentName, dataId, group, tenant); string md5 = HashUtil.GetMd5(content); cacheData.SetUseLocalConfigInfo(true); cacheData.SetLocalConfigInfoVersion(path.LastWriteTimeUtc.ToTimestamp()); cacheData.SetContent(content); _logger?.LogWarning( "[{0}] [failover-change] failover file created. dataId={1}, group={2}, tenant={3}, md5={4}, content={5}", agentName, dataId, group, tenant, md5, ContentUtils.TruncateContent(content)); return; } // If use local config info, then it doesn't notify business listener and notify after getting from server. if (cacheData.IsUseLocalConfig && !path.Exists) { cacheData.SetUseLocalConfigInfo(false); _logger?.LogWarning( "[{0}] [failover-change] failover file deleted. dataId={1}, group={2}, tenant={3}", agentName, dataId, group, tenant); return; } // When it changed. if (cacheData.IsUseLocalConfig && path.Exists && cacheData.GetLocalConfigInfoVersion() != path.LastWriteTimeUtc.ToTimestamp()) { string content = await FileLocalConfigInfoProcessor.GetFailoverAsync(agentName, dataId, group, tenant); string md5 = HashUtil.GetMd5(content); cacheData.SetUseLocalConfigInfo(true); cacheData.SetLocalConfigInfoVersion(path.LastWriteTimeUtc.ToTimestamp()); cacheData.SetContent(content); _logger?.LogWarning( "[{0}] [failover-change] failover file created. dataId={1}, group={2}, tenant={3}, md5={4}, content={5}", agentName, dataId, group, tenant, md5, ContentUtils.TruncateContent(content)); } }
private Timer LongPolling(int taskId) { return(new Timer( async x => { var cacheDatas = new List <CacheData>(); var inInitializingCacheList = new List <string>(); int selfTaskId = -1; int.TryParse(x.ToString(), out selfTaskId); try { foreach (var cacheData in _cacheMap.Values) { // no listener should stop here. if (cacheData.TaskId == selfTaskId && cacheData.GetListeners() != null && cacheData.GetListeners().Any()) { cacheDatas.Add(cacheData); try { await CheckLocalConfig(_agent.GetName(), cacheData); if (cacheData.IsUseLocalConfig) { cacheData.CheckListenerMd5(); } } catch (Exception ex) { _logger?.LogError(ex, "get local config info error"); } } } var changedGroupKeys = await CheckUpdateDataIds(cacheDatas, inInitializingCacheList); foreach (string groupKey in changedGroupKeys) { string[] key = GroupKey.ParseKey(groupKey); string dataId = key[0]; string group = key[1]; string tenant = null; if (key.Length == 3) { tenant = key[2]; } try { List <string> ct = await GetServerConfig(dataId, group, tenant, 3000L, true); if (_cacheMap.TryGetValue(GroupKey.GetKeyTenant(dataId, group, tenant), out var cache)) { cache.SetContent(ct[0]); if (ct[1] != null) { cache.Type = ct[1]; } _logger?.LogInformation("[{0}] [data-received] dataId={1}, group={2}, tenant={3}, md5={4}, content={5}, type={6}", _agent.GetName(), dataId, group, tenant, cache.Md5, ContentUtils.TruncateContent(ct[0]), ct[1]); } } catch (Exception ioe) { _logger?.LogError(ioe, "[{0}] [get-update] get changed config exception. dataId={0}, group={2}, tenant={3}", _agent.GetName(), dataId, group, tenant); } } foreach (var cacheData in cacheDatas) { if (!cacheData.IsInitializing || inInitializingCacheList.Contains(GroupKey.GetKeyTenant(cacheData.DataId, cacheData.Group, cacheData.Tenant))) { cacheData.CheckListenerMd5(); cacheData.IsInitializing = false; } } inInitializingCacheList.Clear(); if (_longPollingMap.TryGetValue(selfTaskId, out var t)) { t.Change(1, Timeout.Infinite); } } catch (Exception ex) { _logger?.LogError(ex, "longPolling error"); if (_longPollingMap.TryGetValue(selfTaskId, out var t)) { t.Change(_taskPenaltyTime, Timeout.Infinite); } } }, taskId, 0, Timeout.Infinite)); }
protected override async Task <bool> PublishConfig(string dataId, string group, string tenant, string appName, string tag, string betaIps, string content) { group = ParamUtils.Null2DefaultGroup(group); ParamUtils.CheckParam(dataId, group, content); ConfigRequest cr = new ConfigRequest(); cr.SetDataId(dataId); cr.SetTenant(tenant); cr.SetGroup(group); cr.SetContent(content); // _configFilterChainManager.doFilter(cr, null); content = cr.GetContent(); string url = Constants.CONFIG_CONTROLLER_PATH; var parameters = new Dictionary <string, string>(6); parameters["dataId"] = dataId; parameters["group"] = group; parameters["content"] = content; if (tenant.IsNotNullOrWhiteSpace()) { parameters["tenant"] = tenant; } if (appName.IsNotNullOrWhiteSpace()) { parameters["appName"] = appName; } if (tag.IsNotNullOrWhiteSpace()) { parameters["tag"] = tag; } var headers = new Dictionary <string, string>(1); if (betaIps.IsNotNullOrWhiteSpace()) { headers["betaIps"] = betaIps; } HttpResponseMessage result = null; try { var timeOut = _options.DefaultTimeOut > 0 ? _options.DefaultTimeOut : POST_TIMEOUT; result = await HttpPost(url, headers, parameters, "", timeOut); } catch (Exception ex) { _logger?.LogWarning( ex, "[{0}] [publish-single] exception, dataId={1}, group={2}, tenant={3}", _agent.GetName(), dataId, group, tenant); return(false); } if (result.StatusCode == System.Net.HttpStatusCode.OK) { _logger?.LogInformation( "[{0}] [publish-single] ok, dataId={1}, group={2}, tenant={3}, config={4}", _agent.GetName(), dataId, group, tenant, ContentUtils.TruncateContent(content)); return(true); } else if (result.StatusCode == System.Net.HttpStatusCode.Forbidden) { _logger?.LogWarning( "[{0}] [publish-single] error, dataId={1}, group={2}, tenant={3}, code={4}, msg={5}", _agent.GetName(), dataId, group, tenant, (int)result.StatusCode, result.StatusCode.ToString()); throw new NacosException((int)result.StatusCode, result.StatusCode.ToString()); } else { _logger?.LogWarning( "[{0}] [publish-single] error, dataId={1}, group={2}, tenant={3}, code={4}, msg={5}", _agent.GetName(), dataId, group, tenant, (int)result.StatusCode, result.StatusCode.ToString()); return(false); } }
public async Task <string> GetConfig(string dataId, string group) { if (string.IsNullOrEmpty(dataId)) { throw new ArgumentNullException(nameof(dataId)); } group = Null2DefaultGroup(group); ConfigResponse cr = new ConfigResponse(); cr.DataId = dataId; cr.Tenant = _namespace; cr.Group = group; // 先使用本地缓存 string content = _localConfigInfoProcessor.GetFailover(_agent.GetName(), dataId, group, _namespace); if (!string.IsNullOrEmpty(content)) { _logger.Warn($"[{_agent.GetName()}] [get-config] get failover ok, dataId={dataId}, group={group}, tenant={_namespace}, config={ContentUtils.TruncateContent(content)}"); cr.Content = content; _configFilterChainManager.DoFilter(null, cr); content = cr.Content; return(content); } try { content = await _worker.GetServerConfig(dataId, group, _namespace); cr.Content = content; _configFilterChainManager.DoFilter(null, cr); content = cr.Content; return(content); } catch (Exception ex) { _logger.Warn(ex, $"[{_agent.GetName()}] [get-config] get from server error, dataId={dataId}, group={group}, tenant={_namespace}"); } _logger.Warn($"[{_agent.GetName()}] [get-config] get snapshot ok, dataId={dataId}, tenant={_namespace}, config={ContentUtils.TruncateContent(content)}"); content = _localConfigInfoProcessor.GetSnapshot(_agent.GetName(), dataId, group, _namespace); cr.Content = content; _configFilterChainManager.DoFilter(null, cr); content = cr.Content; return(content); }
private async Task <bool> PublishConfigInner(string tenant, string dataId, string group, string tag, string appName, string betaIps, string content) { if (string.IsNullOrEmpty(dataId)) { throw new ArgumentNullException(nameof(dataId)); } if (string.IsNullOrEmpty(content)) { throw new ArgumentNullException(nameof(content)); } group = Null2DefaultGroup(group); ConfigRequest cr = new ConfigRequest(); cr.DataId = dataId; cr.Tenant = tenant; cr.Group = group; cr.Content = content; _configFilterChainManager.DoFilter(cr, null); content = cr.Content; string url = Constants.CONFIG_CONTROLLER_PATH; var paramValue = new Dictionary <string, string>(); paramValue.Add("dataId", dataId); paramValue.Add("group", group); paramValue.Add("content", content); if (!string.IsNullOrEmpty(tenant)) { paramValue.Add("tenant", tenant); } if (!string.IsNullOrEmpty(appName)) { paramValue.Add("appName", appName); } if (!string.IsNullOrEmpty(tag)) { paramValue.Add("tag", tag); } var headers = new Dictionary <string, string>(); if (!string.IsNullOrEmpty(betaIps)) { headers.Add("betaIps", betaIps); } try { string result = await _agent.Post(url, headers, paramValue); if (string.IsNullOrEmpty(result) || result == "false") { _logger.Warn($"[{_agent.GetName()}] [publish-single] error, dataId={dataId}, group={group}, tenant={tenant}"); return(false); } _logger.Info($"[{_agent.GetName()}] [publish-single] ok, dataId={dataId}, group={group}, tenant={tenant}, config={ContentUtils.TruncateContent(content)}"); return(true); } catch (Exception ex) { _logger.Warn(ex, $"[{_agent.GetName()}] [publish-single] error, dataId={dataId}, group={group}, tenant={tenant}"); return(false); } }
protected override async Task <bool> PublishConfig(string dataId, string group, string tenant, string appName, string tag, string betaIps, string content, string encryptedDataKey, string casMd5, string type) { try { var request = new ConfigPublishRequest(dataId, group, tenant, content); request.PutAdditonalParam(ConfigConstants.TAG, tag); request.PutAdditonalParam(ConfigConstants.APP_NAME, appName); request.PutAdditonalParam(ConfigConstants.BETAIPS, betaIps); request.PutAdditonalParam(ConfigConstants.TYPE, type); request.PutAdditonalParam(ConfigConstants.ENCRYPTED_DATA_KEY, encryptedDataKey); var response = await RequestProxy(GetOneRunningClient(), request).ConfigureAwait(false); if (!response.IsSuccess()) { _logger?.LogWarning("[{0}] [publish-single] fail, dataId={1}, group={2}, tenant={3}, code={4}, msg={5}", this.GetName(), dataId, group, tenant, response.ErrorCode, response.Message); return(false); } else { _logger?.LogInformation("[{0}] [publish-single] ok, dataId={1}, group={2}, tenant={3}, config={4}", this.GetName(), dataId, group, tenant, ContentUtils.TruncateContent(content)); return(true); } } catch (Exception ex) { _logger?.LogWarning(ex, "[{0}] [publish-single] error, dataId={1}, group={2}, tenant={3}, code={4}", this.GetName(), dataId, group, tenant, "unkonw"); return(false); } }
private Timer LongPolling(int taskId) { return(new Timer(async x => { var cacheDatas = new List <CacheData>(); var inInitializingCacheList = new List <string>(); int selfTaskId = -1; int.TryParse(x.ToString(), out selfTaskId); try { foreach (var cacheData in _cacheMap.Values) { if (cacheData.TaskId == selfTaskId) { cacheDatas.Add(cacheData); try { CheckLocalConfig(cacheData); if (cacheData.IsUseLocalConfig) { cacheData.CheckListenerMD5(); } } catch (Exception ex) { _logger.Error(ex, "get local config info error"); } } } var changedGroupKeys = await CheckUpdateDataIds(cacheDatas, inInitializingCacheList); foreach (string groupKey in changedGroupKeys) { string[] key = GroupKey.ParseKey(groupKey); string dataId = key[0]; string group = key[1]; string tenant = null; if (key.Length == 3) { tenant = key[2]; } try { string content = await GetServerConfig(dataId, group, tenant); CacheData cache = null; if (_cacheMap.TryGetValue(GroupKey.GetKeyTenant(dataId, group, tenant), out cache)) { cache.Content = content; _logger.Info($"[{_agent.GetName()}] [data-received] dataId={dataId}, group={group}, tenant={tenant}, md5={cache.MD5}, content={ContentUtils.TruncateContent(content)}"); } } catch (Exception ex) { _logger.Error(ex, $"[{_agent.GetName()}] [get-update] get changed config exception. dataId={dataId}, group={group}, tenant={tenant}"); } } foreach (var cacheData in cacheDatas) { if (!cacheData.IsInitializing || inInitializingCacheList.Contains(GroupKey.GetKeyTenant(cacheData.DataId, cacheData.Group, cacheData.Tenant))) { cacheData.CheckListenerMD5(); cacheData.IsInitializing = false; } } inInitializingCacheList.Clear(); Timer t = null; if (_longPollingMap.TryGetValue(selfTaskId, out t)) { t.Change(1, Timeout.Infinite); } } catch (Exception ex) { _logger.Error(ex, "longPolling error"); Timer t = null; if (_longPollingMap.TryGetValue(selfTaskId, out t)) { t.Change(_taskPenaltyTime, Timeout.Infinite); } } }, taskId, 0, Timeout.Infinite)); }
/// <summary> /// 校验本地缓存配置 /// </summary> private void CheckLocalConfig(CacheData cacheData) { string dataId = cacheData.DataId; string group = cacheData.Group; string tenant = cacheData.Tenant; string path = _localConfigInfoProcessor.GetFailoverPath(_agent.GetName(), dataId, group, tenant); if (!cacheData.IsUseLocalConfig && File.Exists(path)) { string content = _localConfigInfoProcessor.GetFailover(_agent.GetName(), dataId, group, tenant); string md5 = CacheData.GetMD5String(content); cacheData.IsUseLocalConfig = true; cacheData.LocalConfigLastModified = File.GetLastWriteTime(path).GetTimeStamp(); cacheData.Content = content; _logger.Warn($"[{_agent.GetName()}] [failover-change] failover file created. dataId={dataId}, group={group}, tenant={tenant}, md5={md5}, content={ContentUtils.TruncateContent(content)}"); return; } if (cacheData.IsUseLocalConfig && !File.Exists(path)) { cacheData.IsUseLocalConfig = false; _logger.Warn($"[{_agent.GetName()}] [failover-change] failover file deleted, dataId={dataId}, group={group}, tenant={tenant}"); return; } if (cacheData.IsUseLocalConfig && File.Exists(path) && cacheData.LocalConfigLastModified != File.GetLastWriteTime(path).GetTimeStamp()) { string content = _localConfigInfoProcessor.GetFailover(_agent.GetName(), dataId, group, tenant); string md5 = CacheData.GetMD5String(content); cacheData.IsUseLocalConfig = true; cacheData.LocalConfigLastModified = File.GetLastWriteTime(path).GetTimeStamp(); cacheData.Content = content; _logger.Warn($"[{_agent.GetName()}] [failover-change] failover file changed. dataId={dataId}, group={group}, tenant={tenant}, md5={md5}, content={ContentUtils.TruncateContent(content)}"); } }