Пример #1
0
        private Task <IList <string> > CheckUpdateDataIds(IList <CacheData> cacheDatas, IList <string> inInitializingCacheList)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var cacheData in cacheDatas)
            {
                if (!cacheData.IsUseLocalConfig)
                {
                    sb.Append(cacheData.DataId).Append(Constants.WORD_SEPARATOR);
                    sb.Append(cacheData.Group).Append(Constants.WORD_SEPARATOR);
                    if (string.IsNullOrEmpty(cacheData.Tenant))
                    {
                        sb.Append(cacheData.MD5).Append(Constants.LINE_SEPARATOR);
                    }
                    else
                    {
                        sb.Append(cacheData.MD5).Append(Constants.WORD_SEPARATOR);
                        sb.Append(cacheData.Tenant).Append(Constants.LINE_SEPARATOR);
                    }
                    if (cacheData.IsInitializing)
                    {
                        inInitializingCacheList.Add(GroupKey.GetKeyTenant(cacheData.DataId, cacheData.Group, cacheData.Tenant));
                    }
                }
            }
            bool isInitializingCacheList = inInitializingCacheList.Count > 0;

            return(CheckUpdateConfigStr(sb.ToString(), isInitializingCacheList));
        }
Пример #2
0
        private async Task <List <string> > CheckUpdateDataIds(List <CacheData> cacheDatas, List <string> inInitializingCacheList)
        {
            StringBuilder sb = new StringBuilder();

            foreach (CacheData cacheData in cacheDatas)
            {
                if (!cacheData.IsUseLocalConfig)
                {
                    sb.Append(cacheData.DataId).Append(Constants.WORD_SEPARATOR);
                    sb.Append(cacheData.Group).Append(Constants.WORD_SEPARATOR);
                    if (cacheData.Tenant.IsNullOrWhiteSpace())
                    {
                        sb.Append(cacheData.Md5).Append(Constants.LINE_SEPARATOR);
                    }
                    else
                    {
                        sb.Append(cacheData.Md5).Append(Constants.WORD_SEPARATOR);
                        sb.Append(cacheData.Tenant).Append(Constants.LINE_SEPARATOR);
                    }

                    if (cacheData.IsInitializing)
                    {
                        // It updates when cacheData occours in cacheMap by first time.
                        inInitializingCacheList
                        .Add(GroupKey.GetKeyTenant(cacheData.DataId, cacheData.Group, cacheData.Tenant));
                    }
                }
            }

            var isInitializingCacheList = inInitializingCacheList != null && inInitializingCacheList.Any();

            return(await CheckUpdateConfigStr(sb.ToString(), isInitializingCacheList));
        }
Пример #3
0
        public CommonResponse RequestReply(CommonRequest request)
        {
            if (request is ConfigChangeNotifyRequest configChangeNotifyRequest)
            {
                string groupKey = GroupKey.GetKeyTenant(configChangeNotifyRequest.DataId, configChangeNotifyRequest.Group, configChangeNotifyRequest.Tenant);

                if (_cacheMap.TryGetValue(groupKey, out var cacheData))
                {
                    if (configChangeNotifyRequest.ContentPush &&
                        cacheData.LastModifiedTs < configChangeNotifyRequest.LastModifiedTs)
                    {
                        cacheData.SetContent(configChangeNotifyRequest.Content);
                        cacheData.Type = configChangeNotifyRequest.Type;
                        cacheData.CheckListenerMd5();
                    }

                    cacheData.IsListenSuccess = false;

                    // notifyListenConfig
                    _func.Invoke().Wait();
                }

                _logger?.LogDebug("Config RequestReply => {0}", request.ToJsonString());

                return(new ConfigChangeNotifyResponse());
            }

            return(null);
        }
Пример #4
0
        private async Task <CacheData> AddCacheDataIfAbsent(string dataId, string group, string tenant)
        {
            var cache = GetCache(dataId, group, tenant);

            if (cache != null)
            {
                return(cache);
            }

            string key          = GroupKey.GetKeyTenant(dataId, group, tenant);
            var    cacheFromMap = GetCache(dataId, group, tenant);

            if (cacheFromMap != null)
            {
                cache = cacheFromMap;
                cache.IsInitializing = true;
            }
            else
            {
                cache = new CacheData(_configFilterChainManager, _localConfigInfoProcessor, _agent.GetName(), dataId, group, tenant);
                if (_enableRemoteSyncConfig)
                {
                    string content = await GetServerConfig(dataId, group, tenant);

                    cache.Content = content;
                }
            }

            _cacheMap.AddOrUpdate(key, cache, (k, v) => cache);

            _logger.Info($"[{_agent.GetName()}] [subscribe] {key}");

            return(cache);
        }
Пример #5
0
        private void RemoveCache(string dataId, string group, string tenant)
        {
            var groupKey = GroupKey.GetKeyTenant(dataId, group, tenant);

            _cacheMap.TryRemove(groupKey, out _);

            _logger?.LogInformation("[{0}] [unsubscribe] {1}", GetNameInner(), groupKey);
        }
        internal void RemoveCache(string dataId, string group, string tenant = null)
        {
            string groupKey = tenant == null?GroupKey.GetKey(dataId, group) : GroupKey.GetKeyTenant(dataId, group, tenant);

            _cacheMap.TryRemove(groupKey, out _);

            _logger?.LogInformation("[{0}] [unsubscribe] {1}", this._agent.GetName(), groupKey);
        }
        public CacheData GetCache(string dataId, string group, string tenant)
        {
            if (dataId == null || group == null)
            {
                throw new ArgumentException();
            }

            return(_cacheMap.TryGetValue(GroupKey.GetKeyTenant(dataId, group, tenant), out var cache) ? cache : null);
        }
Пример #8
0
        private void RemoveCache(string dataId, string group, string tenant)
        {
            string    groupKey = GroupKey.GetKeyTenant(dataId, group, tenant);
            CacheData cache;

            _cacheMap.TryRemove(groupKey, out cache);

            _logger.Info($"[{_agent.GetName()}] [unsubscribe] {groupKey}");
        }
Пример #9
0
        private List <string> ParseUpdateDataIdResponse(string response)
        {
            if (string.IsNullOrEmpty(response))
            {
                return(new List <string>());
            }

            response = System.Net.WebUtility.UrlDecode(response);

            var updateList = new List <string>();

            foreach (string dataIdAndGroup in response.SplitByString(Constants.LINE_SEPARATOR))
            {
                if (!string.IsNullOrEmpty(dataIdAndGroup))
                {
                    var keyArr = dataIdAndGroup.SplitByString(Constants.WORD_SEPARATOR);
                    if (keyArr.Length < 2)
                    {
                        continue;
                    }
                    string dataId = keyArr[0];
                    string group  = keyArr[1];
                    if (keyArr.Length == 2)
                    {
                        updateList.Add(GroupKey.GetKey(dataId, group));

                        _logger?.LogInformation(
                            "[{0}] [polling-resp] config changed. dataId={1}, group={2}",
                            _agent.GetName(), dataId, group);
                    }
                    else if (keyArr.Length == 3)
                    {
                        string tenant = keyArr[2];
                        updateList.Add(GroupKey.GetKeyTenant(dataId, group, tenant));

                        _logger?.LogInformation(
                            "[{0}] [polling-resp] config changed. dataId={1}, group={2}, tenant={3}",
                            _agent.GetName(), dataId, group, tenant);
                    }
                    else
                    {
                        _logger?.LogError("[{0}] [polling-resp] invalid dataIdAndGroup error {1}", _agent.GetName(),
                                          dataIdAndGroup);
                    }
                }
            }

            return(updateList);
        }
Пример #10
0
        private CacheData GetCache(string dataId, string group, string tenant)
        {
            if (string.IsNullOrEmpty(dataId))
            {
                throw new ArgumentNullException(nameof(dataId));
            }
            if (string.IsNullOrEmpty(group))
            {
                throw new ArgumentNullException(nameof(group));
            }

            CacheData result = null;

            if (_cacheMap.TryGetValue(GroupKey.GetKeyTenant(dataId, group, tenant), out result))
            {
                return(result);
            }
            return(result);
        }
Пример #11
0
        private IList <string> ParseUpdateDataIdResponse(string response)
        {
            if (string.IsNullOrEmpty(response))
            {
                return(null);
            }

            response = WebUtility.UrlDecode(response);

            var updateList = new List <string>();

            foreach (string dataIdAndGroup in response.Split(Constants.LINE_SEPARATOR))
            {
                if (!string.IsNullOrEmpty(dataIdAndGroup))
                {
                    var keyArr = dataIdAndGroup.Split(Constants.WORD_SEPARATOR);
                    if (keyArr.Length < 2)
                    {
                        continue;
                    }
                    string dataId = keyArr[0];
                    string group  = keyArr[1];
                    if (keyArr.Length == 2)
                    {
                        updateList.Add(GroupKey.GetKey(dataId, group));
                        _logger.Info($"[{_agent.GetName()}] [polling-resp] config changed. dataId={dataId}, group={group}");
                    }
                    else if (keyArr.Length == 3)
                    {
                        string tenant = keyArr[2];
                        updateList.Add(GroupKey.GetKeyTenant(dataId, group, tenant));
                        _logger.Info($"[{_agent.GetName()}] [polling-resp] config changed. dataId={dataId}, group={group}, tenant={tenant}");
                    }
                    else
                    {
                        _logger.Error($"[{_agent.GetName()}] [polling-resp] invalid dataIdAndGroup error {dataIdAndGroup}");
                    }
                }
            }
            return(updateList);
        }
Пример #12
0
        protected async override Task ExecuteConfigListen()
        {
            var listenCachesMap       = new Dictionary <string, List <CacheData> >();
            var removeListenCachesMap = new Dictionary <string, List <CacheData> >();

            // TODO: should update logic here.....
            foreach (var item in _cacheMap.Values)
            {
                if (item.GetListeners() != null && item.GetListeners().Any() && !item.IsListenSuccess)
                {
                    if (!item.IsUseLocalConfig)
                    {
                        if (!listenCachesMap.TryGetValue(item.TaskId.ToString(), out var list))
                        {
                            list = new List <CacheData>();
                            listenCachesMap[item.TaskId.ToString()] = list;
                        }

                        list.Add(item);
                    }
                }
                else if ((item.GetListeners() == null || !item.GetListeners().Any()) && item.IsListenSuccess)
                {
                    if (!item.IsUseLocalConfig)
                    {
                        if (!removeListenCachesMap.TryGetValue(item.TaskId.ToString(), out var list))
                        {
                            list = new List <CacheData>();
                            removeListenCachesMap[item.TaskId.ToString()] = list;
                        }

                        list.Add(item);
                    }
                }
            }

            if (listenCachesMap != null && listenCachesMap.Any())
            {
                foreach (var task in listenCachesMap)
                {
                    var taskId       = task.Key;
                    var listenCaches = task.Value;

                    var request = new ConfigBatchListenRequest()
                    {
                        Listen = true
                    };

                    foreach (var item in listenCaches)
                    {
                        request.AddConfigListenContext(item.Tenant, item.Group, item.DataId, item.Md5);
                    }

                    if (request.ConfigListenContexts != null && request.ConfigListenContexts.Any())
                    {
                        try
                        {
                            var rpcClient = EnsureRpcClient(taskId);

                            var configChangeBatchListenResponse = (ConfigChangeBatchListenResponse)(await RequestProxy(rpcClient, request));

                            if (configChangeBatchListenResponse != null && configChangeBatchListenResponse.IsSuccess())
                            {
                                var changeKeys = new HashSet <string>();

                                if (configChangeBatchListenResponse.ChangedConfigs != null && configChangeBatchListenResponse.ChangedConfigs.Any())
                                {
                                    foreach (var item in configChangeBatchListenResponse.ChangedConfigs)
                                    {
                                        var changeKey = GroupKey.GetKeyTenant(item.DataId, item.Group, item.Tenant);

                                        changeKeys.Add(changeKey);

                                        await RefreshContentAndCheck(changeKey, true);
                                    }
                                }

                                foreach (var item in listenCaches)
                                {
                                    if (!changeKeys.Contains(GroupKey.GetKeyTenant(item.DataId, item.Group, item.Tenant)))
                                    {
                                        item.IsListenSuccess = true;
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger?.LogError(ex, "async listen config change error ");
                        }
                    }
                }
            }

            if (removeListenCachesMap != null && removeListenCachesMap.Any())
            {
                foreach (var task in removeListenCachesMap)
                {
                    var taskId             = task.Key;
                    var removeListenCaches = task.Value;

                    var request = new ConfigBatchListenRequest {
                        Listen = false
                    };

                    foreach (var item in removeListenCaches)
                    {
                        request.AddConfigListenContext(item.Tenant, item.Group, item.DataId, item.Md5);
                    }

                    if (request.ConfigListenContexts != null && request.ConfigListenContexts.Any())
                    {
                        try
                        {
                            RpcClient rpcClient = EnsureRpcClient(taskId);
                            var       response  = await RequestProxy(rpcClient, request);

                            if (response != null && response.IsSuccess())
                            {
                                foreach (var item in removeListenCaches)
                                {
                                    RemoveCache(item.DataId, item.Group, item.Tenant);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger?.LogError(ex, "async remove listen config change error ");
                        }
                    }
                }
            }
        }
Пример #13
0
        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));
        }
Пример #14
0
        protected override async Task <ConfigResponse> QueryConfig(string dataId, string group, string tenant, long readTimeous, bool notify)
        {
            try
            {
                var request = new ConfigQueryRequest(dataId, group, tenant);
                request.PutHeader(ConfigConstants.NOTIFY_HEADER, notify.ToString());

                var rpcClient = GetOneRunningClient();

                if (notify)
                {
                    var key = GroupKey.GetKeyTenant(dataId, group, tenant);
                    if (_cacheMap.TryGetValue(key, out var cacheData))
                    {
                        rpcClient = EnsureRpcClient(cacheData.TaskId.ToString());
                    }
                }

                var response = (ConfigQueryResponse) await RequestProxy(rpcClient, request).ConfigureAwait(false);

                ConfigResponse configResponse = new ConfigResponse();

                if (response.IsSuccess())
                {
                    await FileLocalConfigInfoProcessor.SaveSnapshotAsync(this.GetName(), dataId, group, tenant, response.Content).ConfigureAwait(false);

                    configResponse.SetContent(response.Content);
                    configResponse.SetConfigType(response.ContentType.IsNotNullOrWhiteSpace() ? response.ContentType : "text");

                    // in nacos 2.0.2 still do not return the EncryptedDataKey
                    // so this always be null at this time!!!
                    string encryptedDataKey = response.EncryptedDataKey;

                    await FileLocalConfigInfoProcessor.SaveEncryptDataKeySnapshot(this.GetName(), dataId, group, tenant, encryptedDataKey).ConfigureAwait(false);

                    configResponse.SetEncryptedDataKey(encryptedDataKey);

                    return(configResponse);
                }
                else if (response.ErrorCode.Equals(ConfigQueryResponse.CONFIG_NOT_FOUND))
                {
                    await FileLocalConfigInfoProcessor.SaveSnapshotAsync(this.GetName(), dataId, group, tenant, null).ConfigureAwait(false);

                    await FileLocalConfigInfoProcessor.SaveEncryptDataKeySnapshot(this.GetName(), dataId, group, tenant, null).ConfigureAwait(false);

                    return(configResponse);
                }
                else if (response.ErrorCode.Equals(ConfigQueryResponse.CONFIG_QUERY_CONFLICT))
                {
                    _logger?.LogError(
                        "[{0}] [sub-server-error] get server config being modified concurrently, dataId={1}, group={2}, tenant={3}",
                        GetName(), dataId, group, tenant);
                    throw new NacosException(NacosException.CONFLICT, $"data being modified, dataId={dataId},group={group},tenant={tenant}");
                }
                else
                {
                    _logger?.LogError(
                        "[{0}] [sub-server-error]  dataId={1}, group={2}, tenant={3}, code={4}",
                        GetName(), dataId, group, tenant, response.ToJsonString());
                    throw new NacosException(response.ErrorCode, $"http error, code={response.ErrorCode}, dataId={dataId},group={group},tenant={tenant}");
                }
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "[{0}] [sub-server-error] dataId={1}, group={2}, tenant={3}, code={4} ", GetName(), dataId, group, tenant, ex.Message);
                throw;
            }
        }
Пример #15
0
        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));
        }