diff --git a/README.md b/README.md index fd477c0..dce6ee3 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,12 @@ a libnacos-cli.so and a nacos-cli.out will be generated run `./nacos-cli.out` to perform test on the library -**Note: You need to run a nacos server on your local machine listening on port 8848 to go through the whole test -One of the testcases will test endpoint functionality, so you also need to run a simple http server on port 80 which provides the following content: +**Note:** You need to run a nacos server on your local machine listening on port 8848 to go through the whole test +One of the testcases will test endpoint functionality, so **you also need** to run a simple http server on port 80 which provides the following content: `127.0.0.1:8848` -**on path /endpoints/endpoint0 +**on path /endpoints/endpoint0** ## Integrate the library into your project @@ -403,6 +403,22 @@ int main() { } ``` +### Enabling Authentication + +If your Nacos server is secured with password, you can add the following snippet to any of the examples above to enable authentication: + +```C++ +using namespace nacos; +...... + configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; + configProps[PropertyKeyConst::AUTH_USERNAME] = "username"; + configProps[PropertyKeyConst::AUTH_PASSWORD] = "password"; + NacosServiceFactory *factory = new NacosServiceFactory(configProps); + ConfigService *n = factory->CreateConfigService(); + NamingService *namingSvc = factory->CreateNamingService(); +...... +``` + # About Nacos Nacos (official site: [http://nacos.io](http://nacos.io)) is an easy-to-use platform designed for dynamic service discovery and configuration and service management. It helps you to build cloud native applications and microservices platform easily. diff --git a/README_zh_CN.md b/README_zh_CN.md index 198af2f..aae4550 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -19,8 +19,8 @@ Nacos-sdk-cpp是nacos客戶端的C++版本,它支持服务发现和动态配 运行 `./nacos-cli.out` 以执行客户端的所有testcase -**注意: 你需要在本机运行一个nacos server,监听8848端口以完成所有测试 -其中有个测试将会测试端点(endpoint)功能,所以你需要在本机运行一个http服务器,在路径/endpoints/endpoint0提供下述内容: +**注意:** 你需要在本机运行一个nacos server,监听8848端口以完成所有测试 +其中有个测试将会测试端点(endpoint)功能,**所以你还需要**在本机运行一个http服务器,在路径/endpoints/endpoint0提供下述内容: `127.0.0.1:8848` @@ -398,7 +398,6 @@ int main() { } ``` - ### 启用认证 如果你的服务器启设置了密码,在上述任意一个例子当中加入下述配置,即可启用用户名密码认证: diff --git a/include/Constants.h b/include/Constants.h index 76970da..c082c8a 100644 --- a/include/Constants.h +++ b/include/Constants.h @@ -18,6 +18,12 @@ class Constants { const static NacosString DEFAULT_GROUP; + const static NacosString DEFAULT_CONTEXT_PATH; + + const static NacosString PROTOCOL_VERSION; + + const static NacosString GET_SERVERS_PATH; + const static NacosString APPNAME; const static NacosString UNKNOWN_APP; diff --git a/include/DebugAssertion.h b/include/DebugAssertion.h index e4910a7..7ec7f61 100644 --- a/include/DebugAssertion.h +++ b/include/DebugAssertion.h @@ -37,12 +37,14 @@ do \ #define SHOULD_BE_FALSE(assertion, message) SHOULD_BE_TRUE(!(assertion), (message)) -#define ReleaseResource(x) \ +#ifdef NACOS_AUTH +#define ADD_AUTH_INFO(x) \ do { \ - if ((x) != NULL) \ - delete (x); \ - x = NULL; \ + (x)["nacos.auth.username"] = "nacos"; \ + (x)["nacos.auth.password"] = "nacos"; \ } while (0) +#else +#define ADD_AUTH_INFO(x) +#endif }//namespace nacos - #endif \ No newline at end of file diff --git a/include/NacosExceptions.h b/include/NacosExceptions.h index 7fa5a6d..1c7c2cf 100644 --- a/include/NacosExceptions.h +++ b/include/NacosExceptions.h @@ -6,7 +6,7 @@ namespace nacos{ class NacosException : public std::exception { -private: +protected: int _errcode; NacosString _errmsg; public: @@ -75,6 +75,9 @@ class NacosException : public std::exception { static const int INVALID_FACTORY_CONFIG = 1003; static const int ALL_SERVERS_TRIED_AND_FAILED = 1004; static const int NO_SERVER_AVAILABLE = 1005; + static const int INVALID_LOGIN_CREDENTIAL = 1006; + static const int UNABLE_TO_OPEN_FILE = 1007; + }; class NetworkException : public std::exception { @@ -93,20 +96,13 @@ class NetworkException : public std::exception { const int errorcode() const throw() { return _curlerrcode; }; }; -class IOException : public std::exception { -private: - int _errcode; - NacosString _errmsg; +class IOException : public NacosException { public: - IOException(int errorcode, const char *errormsg) throw(): _errcode(errorcode), _errmsg(errormsg) {}; + IOException(int errorcode, const char *errormsg) throw() : NacosException(errorcode, errormsg) {}; - IOException(int errorcode, const NacosString &errormsg) throw(): _errcode(errorcode), _errmsg(errormsg) {}; + IOException(int errorcode, const NacosString &errormsg) throw() : NacosException(errorcode, errormsg) {}; ~IOException() throw() {}; - - const char *what() const throw() { return _errmsg.c_str(); }; - - const int errorcode() const throw() { return _errcode; }; }; class MalformedConfigException : public NacosException { diff --git a/include/NacosString.h b/include/NacosString.h index 5fcfed6..3727ce9 100644 --- a/include/NacosString.h +++ b/include/NacosString.h @@ -31,6 +31,10 @@ NacosString NacosStringOps::valueOf(T val) { return NULLSTR; } + +template<> +NacosString NacosStringOps::valueOf(bool val); + }//namespace nacos #endif diff --git a/include/Parameters.h b/include/Parameters.h deleted file mode 100644 index a745d5e..0000000 --- a/include/Parameters.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PARAM_H_ -#define __PARAM_H_ -#define DEFAULT_CONTEXT_PATH "nacos" -#define PROTOCOL_VERSION "v1" -#define GET_SERVERS_PATH "ns/operator/servers" -#endif \ No newline at end of file diff --git a/include/PropertyKeyConst.h b/include/PropertyKeyConst.h index ce1cf7a..39b09c4 100644 --- a/include/PropertyKeyConst.h +++ b/include/PropertyKeyConst.h @@ -36,24 +36,26 @@ class PropertyKeyConst { static const NacosString NAMING_POLLING_THREAD_COUNT; - static const NacosString HTTP_REQ_TIMEOUT; - static const NacosString SRVLISTMGR_REFRESH_INTERVAL; - static const NacosString SRVLISTMGR_READ_TIMEOUT; + static const NacosString SERVER_REQ_TIMEOUT; static const NacosString TCP_NAMING_POLL_INTERVAL; static const NacosString CONFIG_LONGPULLLING_TIMEOUT; - static const NacosString CONFIG_GET_TIMEOUT; - static const NacosString HB_FAIL_WAIT_TIME; static const NacosString NACOS_SNAPSHOT_PATH; static const NacosString NACOS_LOG_PATH; + static const NacosString CLIENT_NAME; + static const NacosString AUTH_USERNAME; + static const NacosString AUTH_PASSWORD; + + static const int NACOS_DEFAULT_PORT = 8848; + /*public static class SystemEnv { static const NacosString ALIBABA_ALIWARE_ENDPOINT_PORT = "ALIBABA_ALIWARE_ENDPOINT_PORT"; diff --git a/include/utils/ParamUtils.h b/include/utils/ParamUtils.h index 66814cd..74b9bd0 100644 --- a/include/utils/ParamUtils.h +++ b/include/utils/ParamUtils.h @@ -14,7 +14,7 @@ namespace nacos{ class ParamUtils { public: template - static T getNthElem(const std::list &parm, size_t i) { + static const T &getNthElem(const std::list &parm, size_t i) { assert(parm.size() > i); typename std::list::const_iterator it = parm.begin(); for (size_t skipper = 0; skipper < i; skipper++) { @@ -192,6 +192,23 @@ class ParamUtils { list.push_back(key); list.push_back(value); } + + static NacosString toLower(const NacosString &str) { + NacosString lowerCaseString; + for (NacosString::const_iterator it = str.begin(); it != str.end(); it++) { + lowerCaseString.push_back(tolower(*it)); + } + + return lowerCaseString; + } + + static bool equals_ic(const NacosString &str1, const NacosString &str2) { + + NacosString lcase_str1 = toLower(str1); + NacosString lcase_str2 = toLower(str2); + + return lcase_str1 == lcase_str2; + } }; }//namespace nacos diff --git a/src/Constants.cpp b/src/Constants.cpp index 4ffb84f..3a3ba67 100644 --- a/src/Constants.cpp +++ b/src/Constants.cpp @@ -12,6 +12,9 @@ const NacosString Constants::CLIENT_VERSION = "3.0.0"; const int Constants::DATA_IN_BODY_VERSION = 204; const NacosString Constants::DEFAULT_GROUP = "DEFAULT_GROUP"; +const NacosString Constants::DEFAULT_CONTEXT_PATH = "nacos"; +const NacosString Constants::PROTOCOL_VERSION = "v1"; +const NacosString Constants::GET_SERVERS_PATH = "ns/operator/servers"; const NacosString Constants::APPNAME = "AppName"; diff --git a/src/PropertyKeyConst.cpp b/src/PropertyKeyConst.cpp index f1dc220..e2c6d2d 100644 --- a/src/PropertyKeyConst.cpp +++ b/src/PropertyKeyConst.cpp @@ -31,19 +31,18 @@ const NacosString PropertyKeyConst::NAMING_CLIENT_BEAT_THREAD_COUNT = "namingCli const NacosString PropertyKeyConst::NAMING_POLLING_THREAD_COUNT = "namingPollingThreadCount"; -const NacosString PropertyKeyConst::HTTP_REQ_TIMEOUT = "httpReqTimeout"; - const NacosString PropertyKeyConst::SRVLISTMGR_REFRESH_INTERVAL = "serverListMgr.refreshInterval"; -const NacosString PropertyKeyConst::SRVLISTMGR_READ_TIMEOUT = "serverListMgr.readTimeout"; +const NacosString PropertyKeyConst::SERVER_REQ_TIMEOUT = "nacos.server.reqtimeout"; const NacosString PropertyKeyConst::TCP_NAMING_POLL_INTERVAL = "naming.poller.interval"; const NacosString PropertyKeyConst::CONFIG_LONGPULLLING_TIMEOUT = "config.longpulling.timeout"; -const NacosString PropertyKeyConst::CONFIG_GET_TIMEOUT = "config.get.timeout"; - const NacosString PropertyKeyConst::HB_FAIL_WAIT_TIME = "naming.heartbeat.failwait"; const NacosString PropertyKeyConst::NACOS_SNAPSHOT_PATH = "nacos.snapshot.path"; const NacosString PropertyKeyConst::NACOS_LOG_PATH = "nacos.log.path"; +const NacosString PropertyKeyConst::CLIENT_NAME = "nacos.client.name"; +const NacosString PropertyKeyConst::AUTH_USERNAME = "nacos.auth.username"; +const NacosString PropertyKeyConst::AUTH_PASSWORD = "nacos.auth.password"; }//namespace nacos diff --git a/src/config/AppConfigManager.cpp b/src/config/AppConfigManager.cpp index cfb3a6f..d912366 100644 --- a/src/config/AppConfigManager.cpp +++ b/src/config/AppConfigManager.cpp @@ -5,9 +5,9 @@ #include "PropertyKeyConst.h" #include "IOUtils.h" #include "NacosExceptions.h" -#include "Parameters.h" #include "utils/DirUtils.h" #include +#include using namespace std; @@ -15,6 +15,15 @@ namespace nacos{ NacosString AppConfigManager::LINE_SEPARATOR = "\n"; NacosString AppConfigManager::KV_SEPARATOR = "="; + +bool AppConfigManager::nacosAuthEnabled() { + if (contains(PropertyKeyConst::AUTH_USERNAME) && contains(PropertyKeyConst::AUTH_PASSWORD)) { + return true; + } else { + return false; + } +} + Properties AppConfigManager::parseConfigFile(const NacosString &file) { Properties parsedConfig; NacosString confContent = IOUtils::readStringFromFile(file, NULLSTR);//TODO: add encoding support @@ -71,21 +80,24 @@ void AppConfigManager::clearConfig() { appConfig.clear(); } -NacosString AppConfigManager::get(const NacosString &key) const { +const NacosString &AppConfigManager::get(const NacosString &key) { if (appConfig.count(key) == 0) { return NULLSTR; } - Properties copyProps = appConfig; if (key.compare(PropertyKeyConst::NAMESPACE) == 0 - && copyProps[PropertyKeyConst::NAMESPACE].compare("Public") == 0) + && appConfig[PropertyKeyConst::NAMESPACE].compare("Public") == 0) { return NULLSTR; } - return copyProps[key]; + return appConfig[key]; } void AppConfigManager::set(const NacosString &key, const NacosString &value) { + //Special case handle + if (key.compare(PropertyKeyConst::SERVER_REQ_TIMEOUT) == 0) { + _serverReqTimeout = atoi(value.c_str()); + } appConfig[key] = value; } @@ -107,19 +119,18 @@ AppConfigManager::AppConfigManager(const NacosString &_configFile) { void AppConfigManager::initDefaults() { appConfig.clear(); //appConfig[PropertyKeyConst::NAMESPACE] = "public"; - appConfig[PropertyKeyConst::HTTP_REQ_TIMEOUT] = "50000"; - appConfig[PropertyKeyConst::SRVLISTMGR_REFRESH_INTERVAL] = "30000"; - appConfig[PropertyKeyConst::SRVLISTMGR_READ_TIMEOUT] = "3000"; - appConfig[PropertyKeyConst::CONTEXT_PATH] = DEFAULT_CONTEXT_PATH; - appConfig[PropertyKeyConst::TCP_NAMING_POLL_INTERVAL] = "30000";//30 secs by default - appConfig[PropertyKeyConst::CONFIG_LONGPULLLING_TIMEOUT] = "30000";//ms - appConfig[PropertyKeyConst::CONFIG_GET_TIMEOUT] = "3000";//ms - appConfig[PropertyKeyConst::HB_FAIL_WAIT_TIME] = "20000";//ms + set(PropertyKeyConst::SRVLISTMGR_REFRESH_INTERVAL, "30000"); + set(PropertyKeyConst::SERVER_REQ_TIMEOUT, "3000"); + set(PropertyKeyConst::CONTEXT_PATH, Constants::DEFAULT_CONTEXT_PATH); + set(PropertyKeyConst::TCP_NAMING_POLL_INTERVAL, "30000");//30 secs by default + set(PropertyKeyConst::CONFIG_LONGPULLLING_TIMEOUT, "30000");//ms + set(PropertyKeyConst::HB_FAIL_WAIT_TIME, "20000");//ms + set(PropertyKeyConst::CLIENT_NAME, "default"); NacosString homedir = DirUtils::getHome(); - appConfig[PropertyKeyConst::NACOS_LOG_PATH] = homedir + Constants::FILE_SEPARATOR + "nacos" + Constants::FILE_SEPARATOR + "log"; - appConfig[PropertyKeyConst::NACOS_SNAPSHOT_PATH] = homedir + Constants::FILE_SEPARATOR + "nacos" + Constants::FILE_SEPARATOR + "snapshot"; + set(PropertyKeyConst::NACOS_LOG_PATH, homedir + Constants::FILE_SEPARATOR + "nacos" + Constants::FILE_SEPARATOR + "log"); + set(PropertyKeyConst::NACOS_SNAPSHOT_PATH, homedir + Constants::FILE_SEPARATOR + "nacos" + Constants::FILE_SEPARATOR + "snapshot"); log_info("DEFAULT_LOG_PATH:%s\n", appConfig[PropertyKeyConst::NACOS_LOG_PATH].c_str()); log_info("DEFAULT_SNAPSHOT_PATH:%s\n", appConfig[PropertyKeyConst::NACOS_SNAPSHOT_PATH].c_str()); } @@ -128,7 +139,8 @@ void AppConfigManager::initDefaults() { void AppConfigManager::applyConfig(Properties &rhs) { for (map::iterator it = rhs.begin(); it != rhs.end(); it++) { - appConfig[it->first] = it->second; + set(it->first, it->second); } } + }//namespace nacos \ No newline at end of file diff --git a/src/config/AppConfigManager.h b/src/config/AppConfigManager.h index 426d8aa..0e6182f 100644 --- a/src/config/AppConfigManager.h +++ b/src/config/AppConfigManager.h @@ -16,6 +16,7 @@ class AppConfigManager { static NacosString LINE_SEPARATOR; static NacosString KV_SEPARATOR; + volatile long _serverReqTimeout; AppConfigManager(); @@ -26,6 +27,10 @@ class AppConfigManager { void applyConfig(Properties &rhs); public: + bool nacosAuthEnabled(); + + long getServeReqTimeout() const { return _serverReqTimeout; }; + bool isReloadable() const { return reloadable; }; AppConfigManager(Properties &props); @@ -38,7 +43,7 @@ class AppConfigManager { void clearConfig(); - NacosString get(const NacosString &key) const; + const NacosString &get(const NacosString &key); bool contains(const NacosString &key) const; diff --git a/src/config/ConcurrentDiskUtil.cpp b/src/config/ConcurrentDiskUtil.cpp index d21d8ee..da712cb 100644 --- a/src/config/ConcurrentDiskUtil.cpp +++ b/src/config/ConcurrentDiskUtil.cpp @@ -19,7 +19,8 @@ NacosString ConcurrentDiskUtil::getFileContent(const NacosString &file, const NacosString &charsetName) throw(IOException) { if (IOUtils::checkNotExistOrNotFile(file)) { //TODO:add errorcode - throw IOException(99999, "checkNotExistOrNotFile failed, unable to access the file, maybe it doesn't exist."); + throw IOException(NacosException::FILE_NOT_FOUND, + "checkNotExistOrNotFile failed, unable to access the file, maybe it doesn't exist."); } size_t toRead = IOUtils::getFileSize(file); FILE *fp = fopen(file.c_str(), "rb"); @@ -27,7 +28,7 @@ ConcurrentDiskUtil::getFileContent(const NacosString &file, const NacosString &c char errbuf[100]; sprintf(errbuf, "Failed to open file for read, errno: %d", errno); //TODO:add errorcode - throw IOException(99999, errbuf); + throw IOException(NacosException::UNABLE_TO_OPEN_FILE, errbuf); } flock(fileno(fp), LOCK_SH); char buf[toRead + 1]; @@ -58,7 +59,7 @@ bool ConcurrentDiskUtil::writeFileContent char errbuf[100]; sprintf(errbuf, "Failed to open file for write, errno: %d", errno); //TODO:add errorcode - throw IOException(99999, errbuf); + throw IOException(NacosException::UNABLE_TO_OPEN_FILE, errbuf); } flock(fileno(fp), LOCK_SH); fwrite(content.c_str(), content.size(), 1, fp); diff --git a/src/config/LocalConfigInfoProcessor.cpp b/src/config/LocalSnapshotManager.cpp similarity index 75% rename from src/config/LocalConfigInfoProcessor.cpp rename to src/config/LocalSnapshotManager.cpp index bf318a2..4082017 100644 --- a/src/config/LocalConfigInfoProcessor.cpp +++ b/src/config/LocalSnapshotManager.cpp @@ -1,164 +1,175 @@ -#include "LocalConfigInfoProcessor.h" -#include -#include -#include -#include -#include -#include "NacosExceptions.h" -#include "NacosString.h" -#include "utils/ParamUtils.h" -#include "utils/DirUtils.h" -#include "SnapShotSwitch.h" -#include "JVMUtil.h" -#include "ConcurrentDiskUtil.h" -#include "IOUtils.h" -#include "Constants.h" -#include "PropertyKeyConst.h" - -namespace nacos{ - -NacosString LocalConfigInfoProcessor::getFailover(const NacosString &serverName, const NacosString &dataId, - const NacosString &group, const NacosString &tenant) { - NacosString localPath = getFailoverFile(serverName, dataId, group, tenant); - - if (IOUtils::checkNotExistOrNotFile(localPath)) { - return NULLSTR; - } - - try { - return readFile(localPath); - } catch (IOException ioe) { - log_error("[%s] get failover error, file: %s, exception:%s", serverName.c_str(), localPath.c_str(), ioe.what()); - return NULLSTR; - } -}; - -/** - * 获取本地缓存文件内容。NULL表示没有本地文件或抛出异常。 - */ -NacosString LocalConfigInfoProcessor::getSnapshot - ( - const NacosString &name, - const NacosString &dataId, - const NacosString &group, - const NacosString &tenant - ) { - if (!SnapShotSwitch::getIsSnapShot()) { - return NULLSTR; - } - NacosString file = getSnapshotFile(name, dataId, group, tenant); - if (IOUtils::checkNotExistOrNotFile(file)) { - return NULLSTR; - } - - try { - return readFile(file); - } catch (IOException ioe) { - log_error("[%s]+get snapshot error, file:%s what:%s\n", name.c_str(), file.c_str(), ioe.what()); - return NULLSTR; - } -}; - -NacosString LocalConfigInfoProcessor::readFile(const NacosString &file) throw(IOException) { - if (IOUtils::checkNotExistOrNotFile(file)) { - return NULLSTR; - } - - if (JVMUtil::isMultiInstance()) { - return ConcurrentDiskUtil::getFileContent(file, Constants::ENCODE); - } else { - return IOUtils::readStringFromFile(file, Constants::ENCODE); - } -}; - -void -LocalConfigInfoProcessor::saveSnapshot(const NacosString &envName, const NacosString &dataId, const NacosString &group, - const NacosString &tenant, const NacosString &config) { - if (!SnapShotSwitch::getIsSnapShot()) { - return; - } - - NacosString file = getSnapshotFile(envName, dataId, group, tenant); - if (isNull(config)) { - int remove_result = remove(file.c_str()); - if (remove_result)//error happens when removing the file - { - log_error("[%s] delete snapshot error, remove() returns %d, errno = %d\n", - envName.c_str(), remove_result, errno); - } - } else { - NacosString parentFile = IOUtils::getParentFile(file); - if (IOUtils::checkNotExistOrNotDir(parentFile)) { - IOUtils::recursivelyCreate(parentFile); - //LOGGER.error("[{}] save snapshot error", envName); - } - - if (JVMUtil::isMultiInstance()) { - ConcurrentDiskUtil::writeFileContent(file, config, Constants::ENCODE); - } else { - IOUtils::writeStringToFile(file, config, Constants::ENCODE); - } - - //LOGGER.error("[" + envName + "] save snapshot error, " + file, ioe); - } -}; - -/** - * 清除snapshot目录下所有缓存文件。 - */ -void LocalConfigInfoProcessor::cleanAllSnapshot() { - std::list rootFile = IOUtils::listFiles(LOCAL_SNAPSHOT_PATH); - - for (std::list::iterator it = rootFile.begin(); it != rootFile.end(); it++) { - //endsWith("_nacos") - if (it->length() >= 6 && (it->rfind("_nacos") == it->length() - 6)) { - IOUtils::cleanDirectory(LOCAL_SNAPSHOT_PATH + "/" + *it); - } - } - //LOGGER.error("clean all snapshot error, " + ioe.toString(), ioe); -}; - -void LocalConfigInfoProcessor::cleanEnvSnapshot(const NacosString &envName) { - NacosString tmp = LOCAL_SNAPSHOT_PATH + "/" + envName + "_nacos"; - tmp += "/snapshot"; - //I think we should remove -tenant also, so for one envname, cache for all tenants within the environment will be purged - NacosString tmp_tenant = tmp + "-tenant"; - IOUtils::cleanDirectory(tmp); - IOUtils::cleanDirectory(tmp_tenant); - log_info("success delete %s-snapshot: %s\n", envName.c_str(), tmp.c_str()); -}; - -NacosString LocalConfigInfoProcessor::getFailoverFile(const NacosString &serverName, const NacosString &dataId, - const NacosString &group, const NacosString &tenant) { - NacosString Failoverfile = LOCAL_SNAPSHOT_PATH + "/" + serverName + "_nacos"; - Failoverfile += "/data"; - if (ParamUtils::isBlank(tenant)) { - Failoverfile += "/config-data"; - } else { - Failoverfile += "/config-data-tenant/"; - Failoverfile += tenant; - } - Failoverfile += "/" + group + "/" + dataId; - return Failoverfile; -}; - -NacosString LocalConfigInfoProcessor::getSnapshotFile(const NacosString &envName, const NacosString &dataId, - const NacosString &group, const NacosString &tenant) { - NacosString filename = LOCAL_SNAPSHOT_PATH + "/" + envName + "_nacos"; - if (isNull(tenant)) { - filename += "/snapshot"; - } else { - filename += "/snapshot-tenant/" + tenant; - } - - filename += "/" + group + "/" + dataId; - return filename; -}; - -LocalConfigInfoProcessor::LocalConfigInfoProcessor(AppConfigManager *appConfigManager) { - this->_appCfgMgr = appConfigManager; - LOCAL_SNAPSHOT_PATH = _appCfgMgr->get(PropertyKeyConst::NACOS_SNAPSHOT_PATH); - - log_debug("LocalConfigInfoProcessor::LocalConfigInfoProcessor() LOCAL_SNAPSHOT_PATH = %s\n", LocalConfigInfoProcessor::LOCAL_SNAPSHOT_PATH.c_str()); -} +#include "LocalSnapshotManager.h" +#include +#include +#include +#include +#include +#include "NacosExceptions.h" +#include "NacosString.h" +#include "utils/ParamUtils.h" +#include "utils/DirUtils.h" +#include "SnapShotSwitch.h" +#include "JVMUtil.h" +#include "ConcurrentDiskUtil.h" +#include "IOUtils.h" +#include "Constants.h" +#include "PropertyKeyConst.h" + +namespace nacos{ + +NacosString LocalSnapshotManager::getFailover(const NacosString &serverName, const NacosString &dataId, + const NacosString &group, const NacosString &tenant) { + NacosString localPath = getFailoverFile(serverName, dataId, group, tenant); + + if (IOUtils::checkNotExistOrNotFile(localPath)) { + log_debug("[%s] failover file %s doesn't exist\n", serverName.c_str(), localPath.c_str()); + return NULLSTR; + } + + try { + return readFile(localPath); + } catch (IOException ioe) { + log_error("[%s] get failover error, file: %s, exception:%s\n", serverName.c_str(), localPath.c_str(), ioe.what()); + return NULLSTR; + } +}; + +/** + * 获取本地缓存文件内容。NULL表示没有本地文件或抛出异常。 + */ +NacosString LocalSnapshotManager::getSnapshot + ( + const NacosString &name, + const NacosString &dataId, + const NacosString &group, + const NacosString &tenant + ) { + if (!SnapShotSwitch::getIsSnapShot()) { + return NULLSTR; + } + NacosString file = getSnapshotFile(name, dataId, group, tenant); + if (IOUtils::checkNotExistOrNotFile(file)) { + return NULLSTR; + } + + try { + return readFile(file); + } catch (IOException ioe) { + log_error("[%s]+get snapshot error, file:%s what:%s\n", name.c_str(), file.c_str(), ioe.what()); + return NULLSTR; + } +}; + +NacosString LocalSnapshotManager::readFile(const NacosString &file) throw(IOException) { + if (IOUtils::checkNotExistOrNotFile(file)) { + return NULLSTR; + } + + if (JVMUtil::isMultiInstance()) { + return ConcurrentDiskUtil::getFileContent(file, Constants::ENCODE); + } else { + return IOUtils::readStringFromFile(file, Constants::ENCODE); + } +}; + +void +LocalSnapshotManager::saveSnapshot(const NacosString &envName, const NacosString &dataId, const NacosString &group, + const NacosString &tenant, const NacosString &config) { + if (!SnapShotSwitch::getIsSnapShot()) { + return; + } + + NacosString file = getSnapshotFile(envName, dataId, group, tenant); + if (isNull(config)) { + int remove_result = remove(file.c_str()); + if (remove_result)//error happens when removing the file + { + //usually we get this error because we are deleting a non-existent file + log_debug("[%s] delete snapshot error, remove() returns %d, errno = %d\n", + envName.c_str(), remove_result, errno); + } + } else { + NacosString parentFile = IOUtils::getParentFile(file); + if (IOUtils::checkNotExistOrNotDir(parentFile)) { + IOUtils::recursivelyCreate(parentFile); + //LOGGER.error("[{}] save snapshot error", envName); + } + + if (JVMUtil::isMultiInstance()) { + ConcurrentDiskUtil::writeFileContent(file, config, Constants::ENCODE); + } else { + IOUtils::writeStringToFile(file, config, Constants::ENCODE); + } + + //LOGGER.error("[" + envName + "] save snapshot error, " + file, ioe); + } +}; + +/** + * 清除snapshot目录下所有缓存文件。 + */ +void LocalSnapshotManager::cleanAllSnapshot() { + std::list rootFile = IOUtils::listFiles(LOCAL_SNAPSHOT_PATH); + + for (std::list::iterator it = rootFile.begin(); it != rootFile.end(); it++) { + //endsWith("_nacos") + if (it->length() >= 6 && (it->rfind("_nacos") == it->length() - 6)) { + IOUtils::cleanDirectory(LOCAL_SNAPSHOT_PATH + "/" + *it); + } + } + //LOGGER.error("clean all snapshot error, " + ioe.toString(), ioe); +}; + +void LocalSnapshotManager::cleanEnvSnapshot(const NacosString &envName) { + NacosString tmp = LOCAL_SNAPSHOT_PATH + "/" + envName + "_nacos"; + tmp += "/snapshot"; + //I think we should remove -tenant also, so for one envname, cache for all tenants within the environment will be purged + NacosString tmp_tenant = tmp + "-tenant"; + IOUtils::cleanDirectory(tmp); + IOUtils::cleanDirectory(tmp_tenant); + log_info("success delete %s-snapshot: %s\n", envName.c_str(), tmp.c_str()); +}; + +NacosString LocalSnapshotManager::getFailoverFile(const NacosString &serverName, const NacosString &dataId, + const NacosString &group, const NacosString &tenant) { + NacosString Failoverfile = LOCAL_SNAPSHOT_PATH + "/" + serverName + "_nacos"; + Failoverfile += "/data"; + if (ParamUtils::isBlank(tenant)) { + Failoverfile += "/config-data"; + } else { + Failoverfile += "/config-data-tenant/"; + Failoverfile += tenant; + } + if (NacosStringOps::isNullStr(group)) { + Failoverfile += "/" + Constants::DEFAULT_GROUP + "/" + dataId; + } else { + Failoverfile += "/" + group + "/" + dataId; + } + return Failoverfile; +}; + +NacosString LocalSnapshotManager::getSnapshotFile(const NacosString &envName, const NacosString &dataId, + const NacosString &group, const NacosString &tenant) { + NacosString filename = LOCAL_SNAPSHOT_PATH + "/" + envName + "_nacos"; + if (isNull(tenant)) { + filename += "/snapshot"; + } else { + filename += "/snapshot-tenant/" + tenant; + } + + if (NacosStringOps::isNullStr(group)) { + filename += "/" + Constants::DEFAULT_GROUP + "/" + dataId; + } else { + filename += "/" + group + "/" + dataId; + } + return filename; +}; + +LocalSnapshotManager::LocalSnapshotManager(AppConfigManager *appConfigManager) { + this->_appCfgMgr = appConfigManager; + LOCAL_SNAPSHOT_PATH = _appCfgMgr->get(PropertyKeyConst::NACOS_SNAPSHOT_PATH); + LOCAL_FAILOVER_PATH = _appCfgMgr->get(PropertyKeyConst::NACOS_SNAPSHOT_PATH); + + log_debug("LocalConfigInfoProcessor::LocalConfigInfoProcessor() LOCAL_SNAPSHOT_PATH = %s\n", LocalSnapshotManager::LOCAL_SNAPSHOT_PATH.c_str()); +} }//namespace nacos \ No newline at end of file diff --git a/src/config/LocalConfigInfoProcessor.h b/src/config/LocalSnapshotManager.h similarity index 88% rename from src/config/LocalConfigInfoProcessor.h rename to src/config/LocalSnapshotManager.h index cd46f72..10ea1fb 100644 --- a/src/config/LocalConfigInfoProcessor.h +++ b/src/config/LocalSnapshotManager.h @@ -1,24 +1,25 @@ -#ifndef __LOC_CFG_INF_PROCESSOR_H_ -#define __LOC_CFG_INF_PROCESSOR_H_ +#ifndef __LOCAL_SNAPSHOT_MGR_H_ +#define __LOCAL_SNAPSHOT_MGR_H_ #include "NacosString.h" #include "NacosExceptions.h" #include "src/config/AppConfigManager.h" /** - * Local Disaster Recovery Directory Tool + * Snapshot/Failover manager * * @author Nacos */ namespace nacos{ -class LocalConfigInfoProcessor { +class LocalSnapshotManager { private: AppConfigManager *_appCfgMgr; NacosString LOCAL_SNAPSHOT_PATH; + NacosString LOCAL_FAILOVER_PATH; public: - LocalConfigInfoProcessor(AppConfigManager *appConfigManager); + LocalSnapshotManager(AppConfigManager *appConfigManager); NacosString getFailover(const NacosString &serverName, const NacosString &dataId, const NacosString &group, const NacosString &tenant); diff --git a/src/config/NacosConfigService.cpp b/src/config/NacosConfigService.cpp index d49b464..00d59e9 100644 --- a/src/config/NacosConfigService.cpp +++ b/src/config/NacosConfigService.cpp @@ -1,55 +1,22 @@ #include "src/config/NacosConfigService.h" +#include "src/security/SecurityManager.h" #include "Constants.h" -#include "Parameters.h" -#include "utils/ParamUtils.h" #include "Debug.h" -#include "src/md5/md5.h" using namespace std; namespace nacos{ -NacosConfigService::NacosConfigService - ( - AppConfigManager *_appConfigManager, - IHttpCli *httpCli, - HttpDelegate *httpDelegate, - ServerListManager *_serverListManager, - ClientWorker *_clientWorker - ) throw(NacosException) { - appConfigManager = _appConfigManager; - _httpCli = httpCli; - svrListMgr = _serverListManager; - _httpDelegate = httpDelegate; - clientWorker = _clientWorker; +NacosConfigService::NacosConfigService(ObjectConfigData *objectConfigData) throw(NacosException) { + _objectConfigData = objectConfigData; + if (_objectConfigData->_appConfigManager->nacosAuthEnabled()) { + _objectConfigData->_securityManager->login(); + _objectConfigData->_securityManager->start(); + } } NacosConfigService::~NacosConfigService() { log_debug("NacosConfigService::~NacosConfigService()\n"); - if (clientWorker != NULL) { - clientWorker->stopListening(); - delete clientWorker; - clientWorker = NULL; - } - - if (_httpDelegate != NULL) { - delete _httpDelegate; - _httpDelegate = NULL; - } - - if (svrListMgr != NULL) { - delete svrListMgr; - svrListMgr = NULL; - } - - if (_httpCli != NULL) { - delete _httpCli; - _httpCli = NULL; - } - - if (appConfigManager != NULL) { - delete appConfigManager; - appConfigManager = NULL; - } + delete _objectConfigData; } NacosString NacosConfigService::getConfig @@ -85,7 +52,34 @@ NacosString NacosConfigService::getConfigInner const NacosString &group, long timeoutMs ) throw(NacosException) { - return clientWorker->getServerConfig(tenant, dataId, group, timeoutMs); + NacosString result = NULLSTR; + + AppConfigManager *_appConfigManager = _objectConfigData->_appConfigManager; + LocalSnapshotManager *_localSnapshotManager = _objectConfigData->_localSnapshotManager; + + NacosString clientName = _appConfigManager->get(PropertyKeyConst::CLIENT_NAME); + result = _localSnapshotManager->getFailover(clientName.c_str(), dataId, group, tenant); + if (!NacosStringOps::isNullStr(result)) { + log_warn("[%s] [get-config] get failover ok, dataId=%s, group=%s, tenant=%s, config=%s", + clientName.c_str(), + dataId.c_str(), + group.c_str(), + tenant.c_str(), + result.c_str()); + return result; + } + + try { + result = _objectConfigData->_clientWorker->getServerConfig(tenant, dataId, group, timeoutMs); + } catch (NacosException &e) { + if (e.errorcode() == NacosException::NO_RIGHT) { + throw e; + } + + const NacosString &clientName = _appConfigManager->get(PropertyKeyConst::CLIENT_NAME); + result = _localSnapshotManager->getSnapshot(clientName, dataId, group, tenant); + } + return result; } bool NacosConfigService::removeConfigInner @@ -98,7 +92,7 @@ bool NacosConfigService::removeConfigInner std::list headers; std::list paramValues; //Get the request url - NacosString path = DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH; + NacosString path = Constants::DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH; HttpResult res; @@ -114,10 +108,11 @@ bool NacosConfigService::removeConfigInner paramValues.push_back(tenant); } - NacosString serverAddr = svrListMgr->getCurrentServerAddr(); + NacosString serverAddr = _objectConfigData->_serverListManager->getCurrentServerAddr(); NacosString url = serverAddr + "/" + path; log_debug("httpDelete Assembled URL:%s\n", url.c_str()); + HttpDelegate *_httpDelegate = _objectConfigData->_httpDelegate; try { res = _httpDelegate->httpDelete(url, headers, paramValues, _httpDelegate->getEncode(), POST_TIMEOUT); } @@ -151,7 +146,7 @@ bool NacosConfigService::publishConfigInner std::list paramValues; NacosString parmGroupid; //Get the request url - NacosString path = DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH; + NacosString path = Constants::DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH; HttpResult res; @@ -178,16 +173,17 @@ bool NacosConfigService::publishConfigInner ParamUtils::addKV(paramValues, "betaIps", betaIps); } - NacosString serverAddr = svrListMgr->getCurrentServerAddr(); + NacosString serverAddr = _objectConfigData->_serverListManager->getCurrentServerAddr(); NacosString url = serverAddr + "/" + path; log_debug("httpPost Assembled URL:%s\n", url.c_str()); + HttpDelegate *_httpDelegate = _objectConfigData->_httpDelegate; try { res = _httpDelegate->httpPost(url, headers, paramValues, _httpDelegate->getEncode(), POST_TIMEOUT); } catch (NetworkException e) { // - log_warn("[{}] [publish-single] exception, dataId=%s, group=%s, msg=%s\n", dataId.c_str(), group.c_str(), + log_warn("[NacosConfigService] [publish-single] exception, dataId=%s, group=%s, msg=%s\n", dataId.c_str(), group.c_str(), tenant.c_str(), e.what()); return false; } @@ -212,10 +208,15 @@ void NacosConfigService::addListener } //TODO:give a constant to this hard-coded number - NacosString cfgcontent = getConfig(dataId, group, 3000); + NacosString cfgcontent; + try { + cfgcontent = getConfig(dataId, group, 3000); + } catch (NacosException &e) { + cfgcontent = ""; + } - clientWorker->addListener(dataId, parmgroup, getNamespace(), cfgcontent, listener); - clientWorker->startListening(); + _objectConfigData->_clientWorker->addListener(dataId, parmgroup, getNamespace(), cfgcontent, listener); + _objectConfigData->_clientWorker->startListening(); } void NacosConfigService::removeListener @@ -229,7 +230,7 @@ void NacosConfigService::removeListener parmgroup = group; } log_debug("NacosConfigService::removeListener()\n"); - clientWorker->removeListener(dataId, parmgroup, getNamespace(), listener); + _objectConfigData->_clientWorker->removeListener(dataId, parmgroup, getNamespace(), listener); } }//namespace nacos diff --git a/src/config/NacosConfigService.h b/src/config/NacosConfigService.h index 7cc67e3..79a7b96 100644 --- a/src/config/NacosConfigService.h +++ b/src/config/NacosConfigService.h @@ -7,15 +7,12 @@ #include "NacosString.h" #include "src/server/ServerListManager.h" #include "Properties.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ class NacosConfigService : public ConfigService { private: - HttpDelegate *_httpDelegate = NULL; - IHttpCli *_httpCli = NULL; - ServerListManager *svrListMgr = NULL; - ClientWorker *clientWorker = NULL; - AppConfigManager *appConfigManager = NULL; + ObjectConfigData *_objectConfigData; //Private Methods NacosConfigService(); @@ -32,7 +29,7 @@ class NacosConfigService : public ConfigService { //NacosString monitorChange(std::map &keysAndContents, long timeoutMs) throw (NacosException); //static NacosString monitorListToString(std::map &keysAndContents); - NacosString getNamespace() const { return appConfigManager->get(PropertyKeyConst::NAMESPACE); }; + NacosString getNamespace() const { return _objectConfigData->_appConfigManager->get(PropertyKeyConst::NAMESPACE); }; public: const static long POST_TIMEOUT = 3000L; @@ -48,32 +45,28 @@ class NacosConfigService : public ConfigService { void removeListener(const NacosString &dataId, const NacosString &group, Listener *listener); - HttpDelegate *getHttpDelegate() const { return _httpDelegate; }; + HttpDelegate *getHttpDelegate() const { return _objectConfigData->_httpDelegate; }; - IHttpCli *getHttpCli() const { return _httpCli; }; + IHttpCli *getHttpCli() const { return _objectConfigData->_httpCli; }; - ServerListManager *getServerListManager() const { return svrListMgr; }; + ServerListManager *getServerListManager() const { return _objectConfigData->_serverListManager; }; - ClientWorker *getClientWorker() const { return clientWorker; }; + ClientWorker *getClientWorker() const { return _objectConfigData->_clientWorker; }; - AppConfigManager *getAppConfigManager() const { return appConfigManager; }; + AppConfigManager *getAppConfigManager() const { return _objectConfigData->_appConfigManager; }; - void setHttpDelegate(HttpDelegate *httpDelegate) { _httpDelegate = httpDelegate; }; + void setHttpDelegate(HttpDelegate *httpDelegate) { _objectConfigData->_httpDelegate = httpDelegate; }; - void setHttpCli(IHttpCli *httpCli) { _httpCli = httpCli; }; + void setHttpCli(IHttpCli *httpCli) { _objectConfigData->_httpCli = httpCli; }; - void setServerListManager(ServerListManager *_svrListMgr) { svrListMgr = _svrListMgr; }; + void setServerListManager(ServerListManager *svrListMgr) { _objectConfigData->_serverListManager = svrListMgr; }; - void setClientWorker(ClientWorker *_clientWorker) { clientWorker = _clientWorker; }; + void setClientWorker(ClientWorker *clientWorker) { _objectConfigData->_clientWorker = clientWorker; }; - void setAppConfigManager(AppConfigManager *_appConfigManager) { appConfigManager = _appConfigManager; }; + void setAppConfigManager(AppConfigManager *appConfigManager) { _objectConfigData->_appConfigManager = appConfigManager; }; //ctors/dtor - NacosConfigService(AppConfigManager *_appConfigManager, - IHttpCli *httpCli, - HttpDelegate *httpDelegate, - ServerListManager *_serverListManager, - ClientWorker *_clientWorker) throw(NacosException); + NacosConfigService(ObjectConfigData *objectConfigData) throw(NacosException); virtual ~NacosConfigService(); }; diff --git a/src/config/SnapShotSwitch.cpp b/src/config/SnapShotSwitch.cpp index a52ceed..282c8d5 100644 --- a/src/config/SnapShotSwitch.cpp +++ b/src/config/SnapShotSwitch.cpp @@ -1,4 +1,4 @@ -#include "LocalConfigInfoProcessor.h" +#include "LocalSnapshotManager.h" #include "SnapShotSwitch.h" namespace nacos{ diff --git a/src/factory/NacosServiceFactory.cpp b/src/factory/NacosServiceFactory.cpp index 2921273..a1824ba 100644 --- a/src/factory/NacosServiceFactory.cpp +++ b/src/factory/NacosServiceFactory.cpp @@ -10,20 +10,36 @@ #include "src/config/NacosConfigService.h" #include "src/http/HttpDelegate.h" #include "src/http/delegate/NoOpHttpDelegate.h" +#include "src/http/delegate/NacosAuthHttpDelegate.h" #include "src/http/HTTPCli.h" #include "src/naming/subscribe/EventDispatcher.h" #include "src/naming/subscribe/TcpNamingServicePoller.h" +#include "src/security/SecurityManager.h" //Unlike Java, in cpp, there's no container, no spring to do the ORM job, so I have to handle it myself namespace nacos{ +void buildSecurityManagerAndHttpDelegate(ObjectConfigData *objectConfigData) { + AppConfigManager *appConfigManager = objectConfigData->_appConfigManager; + if (appConfigManager->nacosAuthEnabled()) { + //nacos authentication is enabled + SecurityManager *securityManager = new SecurityManager(objectConfigData); + objectConfigData->_securityManager = securityManager; + HttpDelegate *httpDelegate = new NacosAuthHttpDelegate(objectConfigData); + objectConfigData->_httpDelegate = httpDelegate; + } else { + HttpDelegate *httpDelegate = new NoOpHttpDelegate(objectConfigData); + objectConfigData->_httpDelegate = httpDelegate; + } +} + //FIXME:Memory leak at initializing stage, e.g.: //when a HttpDelegate is allocated in CreateConfigService, after that an EXCEPTION is thrown during the initialization of ServerListManager //the resource for HttpDelegate is never released NamingService *NacosServiceFactory::CreateNamingService() throw(NacosException) { checkConfig(); - ObjectConfigData objectConfigData; - objectConfigData.name = "config"; + ObjectConfigData *objectConfigData = new ObjectConfigData(NAMING); + objectConfigData->name = "config"; NacosString encoding = "UTF-8"; //Create configuration data and load configs @@ -34,45 +50,41 @@ NamingService *NacosServiceFactory::CreateNamingService() throw(NacosException) } else { appConfigManager = new AppConfigManager(props); } - objectConfigData.appConfigManager = appConfigManager; + objectConfigData->_appConfigManager = appConfigManager; //Create http client IHttpCli *httpCli= new HTTPCli(); - objectConfigData.httpCli = httpCli; + objectConfigData->_httpCli = httpCli; - HttpDelegate *httpDelegate = new NoOpHttpDelegate(httpCli, encoding); + buildSecurityManagerAndHttpDelegate(objectConfigData); //Create server manager - ServerListManager *serverListManager = new ServerListManager(httpDelegate, appConfigManager); - objectConfigData.serverListManager = serverListManager; + ServerListManager *serverListManager = new ServerListManager(objectConfigData); + objectConfigData->_serverListManager = serverListManager; //Create naming service & heartbeat sender - NamingProxy *namingProxy = new NamingProxy(httpDelegate, serverListManager, appConfigManager); - objectConfigData.namingProxy = namingProxy; - BeatReactor *beatReactor = new BeatReactor(namingProxy); - objectConfigData.beatReactor = beatReactor; + NamingProxy *namingProxy = new NamingProxy(objectConfigData); + objectConfigData->_serverProxy = namingProxy; + BeatReactor *beatReactor = new BeatReactor(objectConfigData); + objectConfigData->_beatReactor = beatReactor; EventDispatcher *eventDispatcher = new EventDispatcher(); + objectConfigData->_eventDispatcher = eventDispatcher; - TcpNamingServicePoller *tcpNamingServicePoller = new TcpNamingServicePoller(eventDispatcher, namingProxy, appConfigManager); + TcpNamingServicePoller *tcpNamingServicePoller = new TcpNamingServicePoller(objectConfigData); + objectConfigData->_tcpNamingServicePoller = tcpNamingServicePoller; - NamingService *instance = new NacosNamingService(httpDelegate, - httpCli, - namingProxy, - beatReactor, - eventDispatcher, - tcpNamingServicePoller, - appConfigManager, - serverListManager); + objectConfigData->checkAssembledObject(); + NamingService *instance = new NacosNamingService(objectConfigData); - log_debug("Created config data: %s", objectConfigData.name.c_str()); + log_debug("Created config data: %s", objectConfigData->name.c_str()); return instance; } ConfigService *NacosServiceFactory::CreateConfigService() throw(NacosException) { checkConfig(); - ObjectConfigData objectConfigData; - objectConfigData.name = "name"; + ObjectConfigData *objectConfigData = new ObjectConfigData(CONFIG); + objectConfigData->name = "name"; //Create configuration data and load configs AppConfigManager *appConfigManager = NULL; @@ -82,34 +94,36 @@ ConfigService *NacosServiceFactory::CreateConfigService() throw(NacosException) } else { appConfigManager = new AppConfigManager(props); } - objectConfigData.appConfigManager = appConfigManager; + objectConfigData->_appConfigManager = appConfigManager; //Create http client IHttpCli *httpCli = NULL; httpCli = new HTTPCli(); NacosString encoding = "UTF-8"; - HttpDelegate *httpDelegate = new NoOpHttpDelegate(httpCli, encoding); - objectConfigData.httpCli = httpCli; + objectConfigData->_httpCli = httpCli; + + buildSecurityManagerAndHttpDelegate(objectConfigData); //Create server manager - ServerListManager *serverListManager = new ServerListManager(httpDelegate, appConfigManager); - objectConfigData.serverListManager = serverListManager; + ServerListManager *serverListManager = new ServerListManager(objectConfigData); + objectConfigData->_serverListManager = serverListManager; + + LocalSnapshotManager *localSnapshotManager = new LocalSnapshotManager(appConfigManager); + objectConfigData->_localSnapshotManager = localSnapshotManager; + ClientWorker *clientWorker = new ClientWorker(objectConfigData); + objectConfigData->_clientWorker = clientWorker; + objectConfigData->checkAssembledObject(); - ClientWorker *clientWorker = new ClientWorker(httpDelegate, appConfigManager, serverListManager); - ConfigService *instance = new NacosConfigService(appConfigManager, - httpCli, - httpDelegate, - serverListManager, - clientWorker); + ConfigService *instance = new NacosConfigService(objectConfigData); - log_debug("Created config data: %s", objectConfigData.name.c_str()); + log_debug("Created config data: %s", objectConfigData->name.c_str()); return instance; } NamingMaintainService *NacosServiceFactory::CreateNamingMaintainService() throw(NacosException){ checkConfig(); - ObjectConfigData objectConfigData; - objectConfigData.name = "config"; + ObjectConfigData *objectConfigData = new ObjectConfigData(MAINTAIN); + objectConfigData->name = "config"; NacosString encoding = "UTF-8"; //Create configuration data and load configs @@ -120,29 +134,25 @@ NamingMaintainService *NacosServiceFactory::CreateNamingMaintainService() throw( } else { appConfigManager = new AppConfigManager(props); } - objectConfigData.appConfigManager = appConfigManager; + objectConfigData->_appConfigManager = appConfigManager; //Create http client IHttpCli *httpCli= new HTTPCli(); - objectConfigData.httpCli = httpCli; + objectConfigData->_httpCli = httpCli; - HttpDelegate *httpDelegate = new NoOpHttpDelegate(httpCli, encoding); + buildSecurityManagerAndHttpDelegate(objectConfigData); //Create server manager - ServerListManager *serverListManager = new ServerListManager(httpDelegate, appConfigManager); - objectConfigData.serverListManager = serverListManager; + ServerListManager *serverListManager = new ServerListManager(objectConfigData); + objectConfigData->_serverListManager = serverListManager; //Create naming service & heartbeat sender - NamingProxy *namingProxy = new NamingProxy(httpDelegate, serverListManager, appConfigManager); - objectConfigData.namingProxy = namingProxy; + NamingProxy *namingProxy = new NamingProxy(objectConfigData); + objectConfigData->_serverProxy = namingProxy; - NacosNamingMaintainService *instance = new NacosNamingMaintainService(namingProxy, - httpDelegate, - httpCli, - appConfigManager, - serverListManager); + NacosNamingMaintainService *instance = new NacosNamingMaintainService(objectConfigData); - log_debug("Created config data: %s", objectConfigData.name.c_str()); + log_debug("Created config data: %s", objectConfigData->name.c_str()); return instance; } diff --git a/src/factory/ObjectConfigData.cpp b/src/factory/ObjectConfigData.cpp new file mode 100644 index 0000000..1c0f921 --- /dev/null +++ b/src/factory/ObjectConfigData.cpp @@ -0,0 +1,261 @@ +#include "ObjectConfigData.h" +#include "src/http/HttpDelegate.h" +#include "src/http/IHttpCli.h" +#include "src/naming/NamingProxy.h" +#include "src/naming/beat/BeatReactor.h" +#include "src/naming/subscribe/EventDispatcher.h" +#include "src/naming/subscribe/TcpNamingServicePoller.h" +#include "src/config/AppConfigManager.h" +#include "src/server/ServerListManager.h" +#include "src/listen/ClientWorker.h" +#include "src/config/LocalSnapshotManager.h" +#include "src/security/SecurityManager.h" +namespace nacos{ + +ObjectConfigData::ObjectConfigData(FactoryType theFactoryType) { + factoryType = theFactoryType; + _httpDelegate = NULL; + _httpCli = NULL; + _serverProxy = NULL; + _beatReactor = NULL; + _eventDispatcher = NULL; + _tcpNamingServicePoller = NULL; + _appConfigManager = NULL; + _serverListManager = NULL; + _clientWorker = NULL; + _localSnapshotManager = NULL; + _securityManager = NULL; +} + +void ObjectConfigData::checkNamingService() throw(NacosException) { + if (factoryType != NAMING) { + throw NacosException(NacosException::INVALID_PARAM, "Invalid configuration for naming service, please check"); + } + NACOS_ASSERT(_httpDelegate != NULL); + NACOS_ASSERT(_httpCli != NULL); + NACOS_ASSERT(_serverProxy != NULL); + NACOS_ASSERT(_beatReactor != NULL); + NACOS_ASSERT(_eventDispatcher != NULL); + NACOS_ASSERT(_tcpNamingServicePoller != NULL); + NACOS_ASSERT(_appConfigManager != NULL); + NACOS_ASSERT(_serverListManager != NULL); +} + +void ObjectConfigData::checkConfigService() throw(NacosException) { + if (factoryType != CONFIG) { + throw NacosException(NacosException::INVALID_PARAM, "Invalid configuration for config service, please check"); + } + NACOS_ASSERT(_appConfigManager != NULL); + NACOS_ASSERT(_httpCli != NULL); + NACOS_ASSERT(_httpDelegate != NULL); + NACOS_ASSERT(_serverListManager != NULL); + NACOS_ASSERT(_clientWorker != NULL); + NACOS_ASSERT(_localSnapshotManager != NULL); +} + +void ObjectConfigData::checkMaintainService() throw(NacosException) { + if (factoryType != MAINTAIN) { + throw NacosException(NacosException::INVALID_PARAM, "Invalid configuration for maintain service, please check"); + } + + NACOS_ASSERT(_serverProxy != NULL); + NACOS_ASSERT(_httpDelegate != NULL); + NACOS_ASSERT(_httpCli != NULL); + NACOS_ASSERT(_appConfigManager != NULL); + NACOS_ASSERT(_serverListManager != NULL); +} + +void ObjectConfigData::destroyConfigService() { + + if (_clientWorker != NULL) { + _clientWorker->stopListening(); + } + + if (_securityManager != NULL) { + _securityManager->stop(); + } + + if (_serverListManager) { + _serverListManager->stop(); + } + + if (_clientWorker != NULL) { + _clientWorker->stopListening(); + delete _clientWorker; + _clientWorker = NULL; + } + + if (_httpDelegate != NULL) { + delete _httpDelegate; + _httpDelegate = NULL; + } + + if (_securityManager != NULL) { + delete _securityManager; + _securityManager = NULL; + } + + if (_serverListManager != NULL) { + delete _serverListManager; + _serverListManager = NULL; + } + + if (_httpCli != NULL) { + delete _httpCli; + _httpCli = NULL; + } + + if (_appConfigManager != NULL) { + delete _appConfigManager; + _appConfigManager = NULL; + } +} + +void ObjectConfigData::destroyNamingService() { + + if (_beatReactor != NULL) { + _beatReactor->stop(); + } + + if (_tcpNamingServicePoller != NULL) { + _tcpNamingServicePoller->stop(); + } + + if (_eventDispatcher != NULL) { + _eventDispatcher->stop(); + } + + if (_securityManager != NULL) { + _securityManager->stop(); + } + + if (_serverListManager) { + _serverListManager->stop(); + } + + if (_securityManager != NULL) { + _securityManager->stop(); + } + + if (_httpDelegate != NULL) { + delete _httpDelegate; + _httpDelegate = NULL; + } + + if (_beatReactor != NULL) { + delete _beatReactor; + _beatReactor = NULL; + } + + if (_tcpNamingServicePoller != NULL) + { + delete _tcpNamingServicePoller; + _tcpNamingServicePoller = NULL; + } + + if (_eventDispatcher != NULL) + { + delete _eventDispatcher; + _eventDispatcher = NULL; + } + + if (_serverProxy != NULL) { + delete _serverProxy; + _serverProxy = NULL; + } + + if (_securityManager != NULL) { + delete _securityManager; + _securityManager = NULL; + } + + if (_serverListManager != NULL) { + delete _serverListManager; + _serverListManager = NULL; + } + + if (_httpDelegate != NULL) { + delete _httpDelegate; + _httpDelegate = NULL; + } + + if (_httpCli != NULL) { + delete _httpCli; + _httpCli = NULL; + } + + if (_appConfigManager != NULL) + { + delete _appConfigManager; + _appConfigManager = NULL; + } +} + +void ObjectConfigData::destroyMaintainService() { + if (_serverListManager != NULL) { + _serverListManager->stop(); + } + + if (_securityManager != NULL) { + _securityManager->stop(); + } + + if (_serverProxy != NULL) { + delete _serverProxy; + _serverProxy = NULL; + } + if (_serverListManager != NULL) { + delete _serverListManager; + _serverListManager = NULL; + } + if (_appConfigManager != NULL) { + delete _appConfigManager; + _appConfigManager = NULL; + } + if (_securityManager != NULL) { + delete _securityManager; + _securityManager = NULL; + } + if (_httpDelegate != NULL) { + delete _httpDelegate; + _httpDelegate = NULL; + } + if (_httpCli != NULL) { + delete _httpCli; + _httpCli = NULL; + } +} + +void ObjectConfigData::checkAssembledObject() throw(NacosException) { + switch (factoryType) { + case NAMING: + checkNamingService(); + return; + case CONFIG: + checkConfigService(); + return; + case MAINTAIN: + checkMaintainService(); + break; + default: + abort();//never happens + } +} + +ObjectConfigData::~ObjectConfigData() { + switch (factoryType) { + case NAMING: + destroyNamingService(); + return; + case CONFIG: + destroyConfigService(); + return; + case MAINTAIN: + destroyMaintainService(); + break; + default: + abort();//never happens + } +} + +}//namespace nacos diff --git a/src/factory/ObjectConfigData.h b/src/factory/ObjectConfigData.h index d59bec0..32ad432 100644 --- a/src/factory/ObjectConfigData.h +++ b/src/factory/ObjectConfigData.h @@ -1,21 +1,56 @@ #ifndef __OBJ_CFG_DATA_H_ #define __OBJ_CFG_DATA_H_ -#include "src/naming/NamingProxy.h" #include "naming/NamingService.h" #include "config/ConfigService.h" -#include "src/config/AppConfigManager.h" -#include "src/naming/beat/BeatReactor.h" +#include "NacosExceptions.h" namespace nacos{ +class HttpDelegate; +class IHttpCli; +class NamingProxy; +class BeatReactor; +class EventDispatcher; +class TcpNamingServicePoller; +class AppConfigManager; +class ServerListManager; +class ClientWorker; +class LocalSnapshotManager; +class SecurityManager; + +enum FactoryType { + CONFIG = 0, + NAMING = 1, + MAINTAIN = 2 +}; + class ObjectConfigData { +private: + FactoryType factoryType; + void destroyConfigService(); + void destroyNamingService(); + void destroyMaintainService(); + //These functions are designed to prevent coding problems + //(i.e.: forget to initialize HttpDelegate for a ConfigService) rather than run-time errors + void checkConfigService() throw(NacosException); + void checkNamingService() throw(NacosException); + void checkMaintainService() throw(NacosException); public: + ObjectConfigData(FactoryType theFactoryType); + void checkAssembledObject() throw(NacosException); + ~ObjectConfigData(); NacosString name; - NamingProxy *namingProxy; - BeatReactor *beatReactor; - IHttpCli *httpCli; - AppConfigManager *appConfigManager; - ServerListManager *serverListManager; + HttpDelegate *_httpDelegate; + IHttpCli *_httpCli; + NamingProxy *_serverProxy; + BeatReactor *_beatReactor; + EventDispatcher *_eventDispatcher; + TcpNamingServicePoller *_tcpNamingServicePoller; + AppConfigManager *_appConfigManager; + ServerListManager *_serverListManager; + ClientWorker *_clientWorker; + LocalSnapshotManager *_localSnapshotManager; + SecurityManager *_securityManager; }; }//namespace nacos diff --git a/src/http/HttpDelegate.h b/src/http/HttpDelegate.h index d4eee5d..2594403 100644 --- a/src/http/HttpDelegate.h +++ b/src/http/HttpDelegate.h @@ -12,6 +12,8 @@ */ namespace nacos{ class HttpDelegate { +private: + HttpDelegate *_next = NULL; public: /** * invoke http get method diff --git a/src/http/httpStatCode.h b/src/http/HttpStatus.h similarity index 57% rename from src/http/httpStatCode.h rename to src/http/HttpStatus.h index 80cd68a..c5daad9 100644 --- a/src/http/httpStatCode.h +++ b/src/http/HttpStatus.h @@ -1,159 +1,162 @@ -#ifndef __HTTP_STAT_H_ -#define __HTTP_STAT_H_ +#ifndef __HTTP_STATUS_H_ +#define __HTTP_STATUS_H_ //Copied from JAVA source code HttpURLConnection.java // REMIND: do we want all these?? // Others not here that we do want?? +class HttpStatus +{ +public: /* 2XX: generally "OK" */ /** * HTTP Status-Code 200: OK. */ -#define HTTP_OK 200 +static const int HTTP_OK = 200; /** * HTTP Status-Code 201: Created. */ -#define HTTP_CREATED 201 +static const int HTTP_CREATED = 201; /** * HTTP Status-Code 202: Accepted. */ -#define HTTP_ACCEPTED 202 +static const int HTTP_ACCEPTED = 202; /** * HTTP Status-Code 203: Non-Authoritative Information. */ -#define HTTP_NOT_AUTHORITATIVE 203 +static const int HTTP_NOT_AUTHORITATIVE = 203; /** * HTTP Status-Code 204: No Content. */ -#define HTTP_NO_CONTENT 204 +static const int HTTP_NO_CONTENT = 204; /** * HTTP Status-Code 205: Reset Content. */ -#define HTTP_RESET 205 +static const int HTTP_RESET = 205; /** * HTTP Status-Code 206: Partial Content. */ -#define HTTP_PARTIAL 206 +static const int HTTP_PARTIAL = 206; /* 3XX: relocation/redirect */ /** * HTTP Status-Code 300: Multiple Choices. */ -#define HTTP_MULT_CHOICE 300 +static const int HTTP_MULT_CHOICE = 300; /** * HTTP Status-Code 301: Moved Permanently. */ -#define HTTP_MOVED_PERM 301 +static const int HTTP_MOVED_PERM = 301; /** * HTTP Status-Code 302: Temporary Redirect. */ -#define HTTP_MOVED_TEMP 302 +static const int HTTP_MOVED_TEMP = 302; /** * HTTP Status-Code 303: See Other. */ -#define HTTP_SEE_OTHER 303 +static const int HTTP_SEE_OTHER = 303; /** * HTTP Status-Code 304: Not Modified. */ -#define HTTP_NOT_MODIFIED 304 +static const int HTTP_NOT_MODIFIED = 304; /** * HTTP Status-Code 305: Use Proxy. */ -#define HTTP_USE_PROXY 305 +static const int HTTP_USE_PROXY = 305; /* 4XX: client error */ /** * HTTP Status-Code 400: Bad Request. */ -#define HTTP_BAD_REQUEST 400 +static const int HTTP_BAD_REQUEST = 400; /** * HTTP Status-Code 401: Unauthorized. */ -#define HTTP_UNAUTHORIZED 401 +static const int HTTP_UNAUTHORIZED = 401; /** * HTTP Status-Code 402: Payment Required. */ -#define HTTP_PAYMENT_REQUIRED 402 +static const int HTTP_PAYMENT_REQUIRED = 402; /** * HTTP Status-Code 403: Forbidden. */ -#define HTTP_FORBIDDEN 403 +static const int HTTP_FORBIDDEN = 403; /** * HTTP Status-Code 404: Not Found. */ -#define HTTP_NOT_FOUND 404 +static const int HTTP_NOT_FOUND = 404; /** * HTTP Status-Code 405: Method Not Allowed. */ -#define HTTP_BAD_METHOD 405 +static const int HTTP_BAD_METHOD = 405; /** * HTTP Status-Code 406: Not Acceptable. */ -#define HTTP_NOT_ACCEPTABLE 406 +static const int HTTP_NOT_ACCEPTABLE = 406; /** * HTTP Status-Code 407: Proxy Authentication Required. */ -#define HTTP_PROXY_AUTH 407 +static const int HTTP_PROXY_AUTH = 407; /** * HTTP Status-Code 408: Request Time-Out. */ -#define HTTP_CLIENT_TIMEOUT 408 +static const int HTTP_CLIENT_TIMEOUT = 408; /** * HTTP Status-Code 409: Conflict. */ -#define HTTP_CONFLICT 409 +static const int HTTP_CONFLICT = 409; /** * HTTP Status-Code 410: Gone. */ -#define HTTP_GONE 410 +static const int HTTP_GONE = 410; /** * HTTP Status-Code 411: Length Required. */ -#define HTTP_LENGTH_REQUIRED 411 +static const int HTTP_LENGTH_REQUIRED = 411; /** * HTTP Status-Code 412: Precondition Failed. */ -#define HTTP_PRECON_FAILED 412 +static const int HTTP_PRECON_FAILED = 412; /** * HTTP Status-Code 413: Request Entity Too Large. */ -#define HTTP_ENTITY_TOO_LARGE 413 +static const int HTTP_ENTITY_TOO_LARGE = 413; /** * HTTP Status-Code 414: Request-URI Too Large. */ -#define HTTP_REQ_TOO_LONG 414 +static const int HTTP_REQ_TOO_LONG = 414; /** * HTTP Status-Code 415: Unsupported Media Type. */ -#define HTTP_UNSUPPORTED_TYPE 415 +static const int HTTP_UNSUPPORTED_TYPE = 415; /* 5XX: server error */ @@ -161,36 +164,37 @@ * HTTP Status-Code 500: Internal Server Error. * @deprecated it is misplaced and shouldn't have existed. */ -#define HTTP_SERVER_ERROR 500 +static const int HTTP_SERVER_ERROR = 500; /** * HTTP Status-Code 500: Internal Server Error. */ -#define HTTP_INTERNAL_ERROR 500 +static const int HTTP_INTERNAL_ERROR = 500; /** * HTTP Status-Code 501: Not Implemented. */ -#define HTTP_NOT_IMPLEMENTED 501 +static const int HTTP_NOT_IMPLEMENTED = 501; /** * HTTP Status-Code 502: Bad Gateway. */ -#define HTTP_BAD_GATEWAY 502 +static const int HTTP_BAD_GATEWAY = 502; /** * HTTP Status-Code 503: Service Unavailable. */ -#define HTTP_UNAVAILABLE 503 +static const int HTTP_UNAVAILABLE = 503; /** * HTTP Status-Code 504: Gateway Timeout. */ -#define HTTP_GATEWAY_TIMEOUT 504 +static const int HTTP_GATEWAY_TIMEOUT = 504; /** * HTTP Status-Code 505: HTTP Version Not Supported. */ -#define HTTP_VERSION 505 +static const int HTTP_VERSION = 505; +}; #endif \ No newline at end of file diff --git a/src/http/delegate/NacosAuthHttpDelegate.cpp b/src/http/delegate/NacosAuthHttpDelegate.cpp new file mode 100644 index 0000000..d9188bc --- /dev/null +++ b/src/http/delegate/NacosAuthHttpDelegate.cpp @@ -0,0 +1,74 @@ +// +// Created by liuhanyu on 2020/12/5. +// + +#include "NacosAuthHttpDelegate.h" +#include "src/security/SecurityManager.h" + +using namespace std; + +namespace nacos { +NacosString NacosAuthHttpDelegate::getEncode() const { + return encoding; +} + +NacosAuthHttpDelegate::NacosAuthHttpDelegate(ObjectConfigData *objectConfigData) { + _objectConfigData = objectConfigData; +} + +HttpResult NacosAuthHttpDelegate::httpGet +( + const NacosString &path, + std::list &headers, + std::list ¶mValues, + const NacosString &_encoding, + long readTimeoutMs +) throw(NetworkException) { + HttpResult res; + _objectConfigData->_securityManager->addAccessToken2Req(paramValues); + res = _objectConfigData->_httpCli->httpGet(path, headers, paramValues, _encoding, readTimeoutMs); + return res; +} + +HttpResult NacosAuthHttpDelegate::httpDelete +( + const NacosString &path, + std::list &headers, + std::list ¶mValues, + const NacosString &_encoding, + long readTimeoutMs +) throw(NetworkException) { + HttpResult res; + _objectConfigData->_securityManager->addAccessToken2Req(paramValues); + res = _objectConfigData->_httpCli->httpDelete(path, headers, paramValues, _encoding, readTimeoutMs); + return res; +} + +HttpResult NacosAuthHttpDelegate::httpPost +( + const NacosString &path, + std::list &headers, + std::list ¶mValues, + const NacosString &_encoding, + long readTimeoutMs +) throw(NetworkException) { + HttpResult res; + _objectConfigData->_securityManager->addAccessToken2Req(paramValues); + res = _objectConfigData->_httpCli->httpPost(path, headers, paramValues, _encoding, readTimeoutMs); + return res; +} + +HttpResult NacosAuthHttpDelegate::httpPut +( + const NacosString &path, + std::list &headers, + std::list ¶mValues, + const NacosString &_encoding, + long readTimeoutMs +) throw(NetworkException) { + HttpResult res; + _objectConfigData->_securityManager->addAccessToken2Req(paramValues); + res = _objectConfigData->_httpCli->httpPut(path, headers, paramValues, _encoding, readTimeoutMs); + return res; +} +} \ No newline at end of file diff --git a/src/http/delegate/NacosAuthHttpDelegate.h b/src/http/delegate/NacosAuthHttpDelegate.h new file mode 100644 index 0000000..8f4aa08 --- /dev/null +++ b/src/http/delegate/NacosAuthHttpDelegate.h @@ -0,0 +1,48 @@ +// +// Created by liuhanyu on 2020/12/5. +// + +#ifndef NACOS_SDK_CPP_NACOSAUTHHTTPDELEGATE_H +#define NACOS_SDK_CPP_NACOSAUTHHTTPDELEGATE_H + +#include "NacosExceptions.h" +#include "NacosString.h" +#include "src/http/HttpDelegate.h" +#include "src/factory/ObjectConfigData.h" + +/** + * NoOpHttpDelegate + * + * @author Liu, Hanyu + * Directly send request to HttpCli without any operation + */ +namespace nacos{ + class NacosAuthHttpDelegate : public HttpDelegate { + private: + ObjectConfigData *_objectConfigData; + NacosString encoding; + public: + NacosAuthHttpDelegate(ObjectConfigData *objectConfigData); + + HttpResult httpGet(const NacosString &path, std::list &headers, std::list ¶mValues, + const NacosString &encoding, long readTimeoutMs) throw(NetworkException); + + HttpResult httpPost(const NacosString &path, std::list &headers, std::list ¶mValues, + const NacosString &encoding, long readTimeoutMs) throw(NetworkException); + + virtual HttpResult + httpPut(const NacosString &path, std::list &headers, std::list ¶mValues, + const NacosString &encoding, long readTimeoutMs) throw(NetworkException); + + HttpResult + httpDelete(const NacosString &path, std::list &headers, std::list ¶mValues, + const NacosString &encoding, long readTimeoutMs) throw(NetworkException); + + NacosString getEncode() const; + + virtual ~NacosAuthHttpDelegate() { + }; + }; +}//namespace nacos + +#endif //NACOS_SDK_CPP_NACOSAUTHHTTPDELEGATE_H diff --git a/src/http/delegate/NoOpHttpDelegate.cpp b/src/http/delegate/NoOpHttpDelegate.cpp index cbd5c3f..182b8de 100644 --- a/src/http/delegate/NoOpHttpDelegate.cpp +++ b/src/http/delegate/NoOpHttpDelegate.cpp @@ -1,6 +1,4 @@ -#include #include "NoOpHttpDelegate.h" -#include "Debug.h" using namespace std; @@ -11,11 +9,9 @@ NacosString NoOpHttpDelegate::getEncode() const { NoOpHttpDelegate::NoOpHttpDelegate ( - IHttpCli *httpcli, - const NacosString &_encoding + ObjectConfigData *objectConfigData ) { - encoding = _encoding; - httpCli = httpcli; + _objectConfigData = objectConfigData; } HttpResult NoOpHttpDelegate::httpGet @@ -28,7 +24,7 @@ HttpResult NoOpHttpDelegate::httpGet ) throw(NetworkException) { HttpResult res; - res = httpCli->httpGet(path, headers, paramValues, _encoding, readTimeoutMs); + res = _objectConfigData->_httpCli->httpGet(path, headers, paramValues, _encoding, readTimeoutMs); return res; } @@ -41,7 +37,7 @@ HttpResult NoOpHttpDelegate::httpDelete long readTimeoutMs ) throw(NetworkException) { HttpResult res; - res = httpCli->httpDelete(path, headers, paramValues, _encoding, readTimeoutMs); + res = _objectConfigData->_httpCli->httpDelete(path, headers, paramValues, _encoding, readTimeoutMs); return res; } @@ -55,7 +51,7 @@ HttpResult NoOpHttpDelegate::httpPost ) throw(NetworkException) { HttpResult res; - res = httpCli->httpPost(path, headers, paramValues, _encoding, readTimeoutMs); + res = _objectConfigData->_httpCli->httpPost(path, headers, paramValues, _encoding, readTimeoutMs); return res; } @@ -69,7 +65,7 @@ HttpResult NoOpHttpDelegate::httpPut ) throw(NetworkException) { HttpResult res; - res = httpCli->httpPut(path, headers, paramValues, _encoding, readTimeoutMs); + res = _objectConfigData->_httpCli->httpPut(path, headers, paramValues, _encoding, readTimeoutMs); return res; } diff --git a/src/http/delegate/NoOpHttpDelegate.h b/src/http/delegate/NoOpHttpDelegate.h index 2669e37..fa8d6da 100644 --- a/src/http/delegate/NoOpHttpDelegate.h +++ b/src/http/delegate/NoOpHttpDelegate.h @@ -3,23 +3,22 @@ #include "NacosExceptions.h" #include "NacosString.h" -#include "src/http/HTTPCli.h" #include "src/http/HttpDelegate.h" -#include "src/server/ServerListManager.h" +#include "src/factory/ObjectConfigData.h" /** - * ServerHttpDelegate + * NoOpHttpDelegate * * @author Liu, Hanyu + * Directly send request to HttpCli without any operation */ namespace nacos{ class NoOpHttpDelegate : public HttpDelegate { private: - //Variables + ObjectConfigData *_objectConfigData; NacosString encoding; - IHttpCli *httpCli = NULL; public: - NoOpHttpDelegate(IHttpCli *httpcli, const NacosString &encoding); + NoOpHttpDelegate(ObjectConfigData *objectConfigData); HttpResult httpGet(const NacosString &path, std::list &headers, std::list ¶mValues, const NacosString &encoding, long readTimeoutMs) throw(NetworkException); @@ -38,7 +37,6 @@ class NoOpHttpDelegate : public HttpDelegate { NacosString getEncode() const; virtual ~NoOpHttpDelegate() { - httpCli = NULL; }; }; }//namespace nacos diff --git a/src/json/JSON.cpp b/src/json/JSON.cpp index d51d272..d857adf 100644 --- a/src/json/JSON.cpp +++ b/src/json/JSON.cpp @@ -41,19 +41,17 @@ NacosString JSON::toJSONString(const map &mapinfo) { d.AddMember(k, v, d.GetAllocator()); } - return documentToString(d); } -void JSON::Map2JSONObject(Value &jsonOb, map &mapinfo) { - Document document; +void JSON::Map2JSONObject(Document &d, Value &jsonOb, map &mapinfo) { jsonOb.SetObject(); for (map::iterator it = mapinfo.begin(); it != mapinfo.end(); it++) { Value k; - k.SetString(it->first.c_str(), document.GetAllocator()); + k.SetString(it->first.c_str(), d.GetAllocator()); Value v; - v.SetString(it->second.c_str(), document.GetAllocator()); - jsonOb.AddMember(k, v, document.GetAllocator()); + v.SetString(it->second.c_str(), d.GetAllocator()); + jsonOb.AddMember(k, v, d.GetAllocator()); } } @@ -90,7 +88,7 @@ NacosString JSON::toJSONString(BeatInfo &beatInfo) { AddKV(d, "cluster", beatInfo.cluster); AddKV(d, "scheduled", NacosStringOps::valueOf(beatInfo.scheduled)); Value metadata; - Map2JSONObject(metadata, beatInfo.metadata); + Map2JSONObject(d, metadata, beatInfo.metadata); AddKO(d, "metadata", metadata); //d["port"] = NacosStringOps::valueOf(beatInfo.port); @@ -398,4 +396,22 @@ ServiceInfo2 JSON::Json2ServiceInfo2(const NacosString &nacosString) throw(Nacos return serviceInfo2; } +AccessToken JSON::Json2AccessToken(const NacosString &nacosString) throw(NacosException) +{ + AccessToken accessTokenRes; + Document d; + d.Parse(nacosString.c_str()); + markRequired(d, "accessToken"); + const Value &accessToken = d["accessToken"]; + accessTokenRes.accessToken = accessToken.GetString(); + markRequired(d, "tokenTtl"); + const Value &tokenTtl = d["tokenTtl"]; + accessTokenRes.tokenTtl = tokenTtl.GetInt(); + markRequired(d, "globalAdmin"); + const Value &globalAdmin = d["globalAdmin"]; + accessTokenRes.globalAdmin = globalAdmin.GetBool(); + + return accessTokenRes; +} + }//namespace nacos \ No newline at end of file diff --git a/src/json/JSON.h b/src/json/JSON.h index 91aaff9..c616b6a 100644 --- a/src/json/JSON.h +++ b/src/json/JSON.h @@ -12,6 +12,7 @@ #include "src/server/NacosServerInfo.h" #include "naming/ListView.h" #include "naming/ServiceInfo2.h" +#include "src/security/SecurityManager.h" /** * JSON @@ -26,7 +27,7 @@ class JSON { static NacosString toJSONString(const std::map &mapinfo); - static void Map2JSONObject(rapidjson::Value &jsonOb, std::map &mapinfo); + static void Map2JSONObject(rapidjson::Document &d, rapidjson::Value &jsonOb, std::map &mapinfo); static void JSONObject2Map(std::map &mapinfo, const rapidjson::Value &jsonOb); @@ -48,6 +49,7 @@ class JSON { static ListView Json2ServiceList(const NacosString &nacosString) throw(NacosException); + static AccessToken Json2AccessToken(const NacosString &nacosString) throw(NacosException); }; }//namespace nacos diff --git a/src/listen/ClientWorker.cpp b/src/listen/ClientWorker.cpp index b8ccdcf..868f074 100644 --- a/src/listen/ClientWorker.cpp +++ b/src/listen/ClientWorker.cpp @@ -1,34 +1,29 @@ -#include -#include #include #include "ClientWorker.h" #include "listen/Listener.h" #include "utils/url.h" #include "utils/GroupKey.h" -#include "src/http/httpStatCode.h" #include "src/md5/md5.h" #include "utils/ParamUtils.h" +#include "src/utils/TimeUtils.h" #include "Debug.h" #include "DebugAssertion.h" #include "Constants.h" -#include "Parameters.h" #include "PropertyKeyConst.h" +#include "src/http/HttpStatus.h" using namespace std; namespace nacos{ -ClientWorker::ClientWorker(HttpDelegate *httpDelegate, AppConfigManager *_appConfigManager, ServerListManager *svrListMgr) { +ClientWorker::ClientWorker(ObjectConfigData *objectConfigData) { threadId = 0; stopThread = true; pthread_mutex_init(&watchListMutex, NULL); pthread_mutex_init(&stopThreadMutex, NULL); - _httpDelegate = httpDelegate; - appConfigManager = _appConfigManager; - _svrListMgr = svrListMgr; + _objectConfigData = objectConfigData; - _longPullingTimeoutStr = appConfigManager->get(PropertyKeyConst::CONFIG_LONGPULLLING_TIMEOUT); + _longPullingTimeoutStr = _objectConfigData->_appConfigManager->get(PropertyKeyConst::CONFIG_LONGPULLLING_TIMEOUT); _longPullingTimeout = atoi(_longPullingTimeoutStr.c_str()); - _readTimeout = atoi(appConfigManager->get(PropertyKeyConst::CONFIG_GET_TIMEOUT).c_str()); } ClientWorker::~ClientWorker() { @@ -37,20 +32,43 @@ ClientWorker::~ClientWorker() { cleanUp(); } -int64_t getCurrentTimeInMs() { - struct timeval tv; - gettimeofday(&tv, NULL); - - return tv.tv_sec * 1000 + tv.tv_usec / 1000; +NacosString ClientWorker::getServerConfig +( + const NacosString &tenant, + const NacosString &dataId, + const NacosString &group, + long timeoutMs +) throw(NacosException) { + HttpResult res = getServerConfigHelper(tenant, dataId, group, timeoutMs); + AppConfigManager *_appConfigManager = _objectConfigData->_appConfigManager; + LocalSnapshotManager *localSnapshotManager = _objectConfigData->_localSnapshotManager; + switch (res.code) { + case HttpStatus::HTTP_OK: + localSnapshotManager->saveSnapshot(_appConfigManager->get(PropertyKeyConst::CLIENT_NAME), dataId, group, tenant, res.content); + return res.content; + case HttpStatus::HTTP_NOT_FOUND: + //Update snapshot + localSnapshotManager->saveSnapshot(_appConfigManager->get(PropertyKeyConst::CLIENT_NAME), dataId, group, tenant, NULLSTR); + throw NacosException(NacosException::HTTP_NOT_FOUND, "getServerConfig could not get content for Key " + group + ":" + dataId); + case HttpStatus::HTTP_FORBIDDEN: + //Update snapshot + localSnapshotManager->saveSnapshot(_appConfigManager->get(PropertyKeyConst::CLIENT_NAME), dataId, group, tenant, NULLSTR); + throw NacosException(NacosException::NO_RIGHT, "permission denied for Key " + group + ":" + dataId); + default: + localSnapshotManager->saveSnapshot(_appConfigManager->get(PropertyKeyConst::CLIENT_NAME), dataId, group, tenant, NULLSTR); + throw NacosException(NacosException::SERVER_ERROR, "getServerConfig failed with code:" + NacosStringOps::valueOf(res.code)); + } + return NULLSTR; } -NacosString ClientWorker::getServerConfig - ( - const NacosString &tenant, - const NacosString &dataId, - const NacosString &group, - long timeoutMs - ) throw(NacosException) { + +HttpResult ClientWorker::getServerConfigHelper +( + const NacosString &tenant, + const NacosString &dataId, + const NacosString &group, + long timeoutMs +) throw(NacosException) { std::list headers; std::list paramValues; @@ -67,12 +85,13 @@ NacosString ClientWorker::getServerConfig } //Get the request url - NacosString path = DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH; - NacosString serverAddr = _svrListMgr->getCurrentServerAddr(); + NacosString path = Constants::DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH; + NacosString serverAddr = _objectConfigData->_serverListManager->getCurrentServerAddr(); NacosString url = serverAddr + "/" + path; log_debug("httpGet Assembled URL:%s\n", url.c_str()); HttpResult res; + HttpDelegate *_httpDelegate = _objectConfigData->_httpDelegate; try { res = _httpDelegate->httpGet(url, headers, paramValues, _httpDelegate->getEncode(), timeoutMs); } @@ -80,25 +99,20 @@ NacosString ClientWorker::getServerConfig throw NacosException(NacosException::SERVER_ERROR, e.what()); } - switch (res.code) { - case HTTP_OK: - return res.content; - case HTTP_NOT_FOUND: - return NULLSTR; - } - return NULLSTR; + return res; } + void *ClientWorker::listenerThread(void *parm) { log_debug("Entered watch thread...\n"); ClientWorker *thelistener = (ClientWorker *) parm; while (!thelistener->stopThread) { - int64_t start_time = getCurrentTimeInMs(); + int64_t start_time = TimeUtils::getCurrentTimeInMs(); log_debug("Start watching at %u...\n", start_time); thelistener->performWatch(); - log_debug("Watch function exit at %u...\n", getCurrentTimeInMs()); + log_debug("Watch function exit at %u...\n", TimeUtils::getCurrentTimeInMs()); } return 0; @@ -304,13 +318,14 @@ NacosString ClientWorker::checkListenedKeys() { //Get the request url //TODO:move /listener to constant - NacosString path = DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH + "/listener"; + NacosString path = Constants::DEFAULT_CONTEXT_PATH + Constants::CONFIG_CONTROLLER_PATH + "/listener"; HttpResult res; - NacosString serverAddr = _svrListMgr->getCurrentServerAddr(); + NacosString serverAddr = _objectConfigData->_serverListManager->getCurrentServerAddr(); NacosString url = serverAddr + "/" + path; log_debug("httpPost Assembled URL:%s\n", url.c_str()); + HttpDelegate *_httpDelegate = _objectConfigData->_httpDelegate; try { res = _httpDelegate->httpPost(url, headers, paramValues, _httpDelegate->getEncode(), _longPullingTimeout); } @@ -337,6 +352,7 @@ void ClientWorker::performWatch() { NacosString key = GroupKey::getKeyTenant(dataId, group, tenant); map::iterator listenedDataIter = listeningKeys.find(key); + HttpResult res; //check whether the data being watched still exists if (listenedDataIter != listeningKeys.end()) { log_debug("Found entry for:%s\n", key.c_str()); @@ -344,8 +360,10 @@ void ClientWorker::performWatch() { NacosString updatedcontent = ""; try { - updatedcontent = getServerConfig(listenedList->getTenant(), listenedList->getDataId(), - listenedList->getGroup(), _readTimeout); + res = getServerConfigHelper(listenedList->getTenant(), listenedList->getDataId(), + listenedList->getGroup(), + _objectConfigData->_appConfigManager->getServeReqTimeout()); + updatedcontent = res.content; } catch (NacosException &e) { //Same design as TcpNamingServicePoller @@ -357,10 +375,17 @@ void ClientWorker::performWatch() { break; } log_debug("Data fetched from the server: %s\n", updatedcontent.c_str()); - md5.reset(); - md5.update(updatedcontent.c_str()); - listenedList->setMD5(md5.toString()); - log_debug("MD5 got for that data: %s\n", listenedList->getMD5().c_str()); + + //Bugfix #42, please check github + if (res.code == HttpStatus::HTTP_OK) { + md5.reset(); + md5.update(updatedcontent.c_str()); + listenedList->setMD5(md5.toString()); + log_debug("MD5 got for that data: %s\n", listenedList->getMD5().c_str()); + } else { + listenedList->setMD5(""); + updatedcontent = ""; + } std::map < Listener * , char > const *listenerList = listenedList->getListenerList(); for (std::map::const_iterator listenerIt = listenerList->begin(); listenerIt != listenerList->end(); listenerIt++) { diff --git a/src/listen/ClientWorker.h b/src/listen/ClientWorker.h index 25407bb..5f061f8 100644 --- a/src/listen/ClientWorker.h +++ b/src/listen/ClientWorker.h @@ -11,7 +11,9 @@ #include "OperateItem.h" #include "src/config/AppConfigManager.h" #include "src/server/ServerListManager.h" +#include "src/config/LocalSnapshotManager.h" #include "NacosExceptions.h" +#include "src/factory/ObjectConfigData.h" /** * ClientWorker @@ -29,16 +31,13 @@ class ClientWorker { //dataID||group||tenant -> Cachedata* Mapping std::map listeningKeys; pthread_mutex_t watchListMutex;//TODO:refactor to Mutex - HttpDelegate *_httpDelegate = NULL; - AppConfigManager *appConfigManager = NULL; - ServerListManager *_svrListMgr; + ObjectConfigData *_objectConfigData; //Listener thread related info pthread_t threadId; volatile bool stopThread; pthread_mutex_t stopThreadMutex; - int _readTimeout; int _longPullingTimeout; NacosString _longPullingTimeoutStr; @@ -58,7 +57,7 @@ class ClientWorker { void addDeleteItem(const OperateItem &item); public: - ClientWorker(HttpDelegate *httpDelegate, AppConfigManager *_appConfigManager, ServerListManager *svrListMgr); + ClientWorker(ObjectConfigData *objectConfigData); ~ClientWorker(); @@ -86,6 +85,8 @@ class ClientWorker { NacosString getServerConfig(const NacosString &tenant, const NacosString &dataId, const NacosString &group, long timeoutMs) throw(NacosException); + HttpResult getServerConfigHelper(const NacosString &tenant, const NacosString &dataId, const NacosString &group, + long timeoutMs) throw(NacosException); }; }//namespace nacos diff --git a/src/naming/NacosNamingMaintainService.cpp b/src/naming/NacosNamingMaintainService.cpp index 37de34c..e32f819 100644 --- a/src/naming/NacosNamingMaintainService.cpp +++ b/src/naming/NacosNamingMaintainService.cpp @@ -1,22 +1,16 @@ #include "src/naming/NacosNamingMaintainService.h" +#include "src/security/SecurityManager.h" using namespace std; namespace nacos{ -NacosNamingMaintainService::NacosNamingMaintainService -( - NamingProxy *namingProxy, - HttpDelegate *httpDelegate, - IHttpCli *httpCli, - AppConfigManager *appConfigManager, - ServerListManager *serverListManager -) { - _namingProxy = namingProxy; - _httpDelegate = httpDelegate; - _httpCli = httpCli; - _appConfigManager = appConfigManager; - _serverListManager = serverListManager; +NacosNamingMaintainService::NacosNamingMaintainService(ObjectConfigData *objectConfigData) { + _objectConfigData = objectConfigData; + if (_objectConfigData->_appConfigManager->nacosAuthEnabled()) { + _objectConfigData->_securityManager->login(); + _objectConfigData->_securityManager->start(); + } } bool NacosNamingMaintainService::updateInstance @@ -28,7 +22,7 @@ bool NacosNamingMaintainService::updateInstance Instance paramInstance = instance; paramInstance.serviceName = serviceName; paramInstance.groupName = groupName; - return _namingProxy->updateServiceInstance(paramInstance); + return _objectConfigData->_serverProxy->updateServiceInstance(paramInstance); } ServiceInfo2 NacosNamingMaintainService::queryService @@ -36,7 +30,7 @@ ServiceInfo2 NacosNamingMaintainService::queryService const NacosString &serviceName, const NacosString &groupName ) throw(NacosException) { - return _namingProxy->getServiceInfo(serviceName, groupName); + return _objectConfigData->_serverProxy->getServiceInfo(serviceName, groupName); } bool NacosNamingMaintainService::createService(const ServiceInfo2 &service, naming::Selector *selector) throw(NacosException) { @@ -44,39 +38,19 @@ bool NacosNamingMaintainService::createService(const ServiceInfo2 &service, nami if (!parmServiceInfo.isGroupNameSet()) { parmServiceInfo.setGroupName(Constants::DEFAULT_GROUP); } - return _namingProxy->createServiceInfo(parmServiceInfo, selector); + return _objectConfigData->_serverProxy->createServiceInfo(parmServiceInfo, selector); } bool NacosNamingMaintainService::deleteService(const NacosString &serviceName, const NacosString &groupName) throw(NacosException) { - return _namingProxy->deleteServiceInfo(serviceName, groupName); + return _objectConfigData->_serverProxy->deleteServiceInfo(serviceName, groupName); } bool NacosNamingMaintainService::updateService(const ServiceInfo2 &service, naming::Selector *selector) throw(NacosException) { - return _namingProxy->updateServiceInfo(service, selector); + return _objectConfigData->_serverProxy->updateServiceInfo(service, selector); } NacosNamingMaintainService::~NacosNamingMaintainService() { - if (_namingProxy != NULL) { - delete _namingProxy; - _namingProxy = NULL; - } - if (_serverListManager != NULL) { - _serverListManager->stop(); - delete _serverListManager; - _serverListManager = NULL; - } - if (_appConfigManager != NULL) { - delete _appConfigManager; - _appConfigManager = NULL; - } - if (_httpDelegate != NULL) { - delete _httpDelegate; - _httpDelegate = NULL; - } - if (_httpCli != NULL) { - delete _httpCli; - _httpCli = NULL; - } + delete _objectConfigData; } }//namespace nacos diff --git a/src/naming/NacosNamingMaintainService.h b/src/naming/NacosNamingMaintainService.h index a41b304..fefa391 100644 --- a/src/naming/NacosNamingMaintainService.h +++ b/src/naming/NacosNamingMaintainService.h @@ -7,6 +7,7 @@ #include "src/http/IHttpCli.h" #include "NacosString.h" #include "Properties.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ @@ -22,19 +23,9 @@ namespace nacos{ class NacosNamingMaintainService : public NamingMaintainService { private: NacosNamingMaintainService(); - NamingProxy *_namingProxy; - HttpDelegate *_httpDelegate; - IHttpCli *_httpCli; - AppConfigManager *_appConfigManager; - ServerListManager *_serverListManager; + ObjectConfigData *_objectConfigData; public: - NacosNamingMaintainService( - NamingProxy *namingProxy, - HttpDelegate *httpDelegate, - IHttpCli *httpCli, - AppConfigManager *appConfigManager, - ServerListManager *serverListManager - ); + NacosNamingMaintainService(ObjectConfigData *objectConfigData); bool updateInstance(const NacosString &serviceName, const NacosString & groupName, const Instance &instance) throw(NacosException); ServiceInfo2 queryService(const NacosString &serviceName, const NacosString &groupName) throw(NacosException); bool createService(const ServiceInfo2 &service, naming::Selector *selector) throw(NacosException); diff --git a/src/naming/NacosNamingService.cpp b/src/naming/NacosNamingService.cpp index fc3d8c3..c3f0dfa 100644 --- a/src/naming/NacosNamingService.cpp +++ b/src/naming/NacosNamingService.cpp @@ -10,64 +10,19 @@ using namespace std; using nacos::naming::selectors::Selector; namespace nacos{ -NacosNamingService::NacosNamingService(HttpDelegate *httpDelegate, IHttpCli *httpCli, NamingProxy *_serverProxy, BeatReactor *_beatReactor, - EventDispatcher *eventDispatcher, TcpNamingServicePoller *tcpNamingServicePoller, - AppConfigManager *appConfigManager, ServerListManager *serverListManager) { - _appConfigMgr = appConfigManager; - _httpCli = httpCli; - _httpDelegate = httpDelegate; - serverProxy = _serverProxy; - beatReactor = _beatReactor; - _eventDispatcher = eventDispatcher; - _tcpNamingServicePoller = tcpNamingServicePoller; - _serverListManager = serverListManager; - beatReactor->start(); - _tcpNamingServicePoller->start(); +NacosNamingService::NacosNamingService(ObjectConfigData *objectConfigData) { + _objectConfigData = objectConfigData; + _objectConfigData->_beatReactor->start(); + _objectConfigData->_tcpNamingServicePoller->start(); + + if (_objectConfigData->_appConfigManager->nacosAuthEnabled()) { + _objectConfigData->_securityManager->login(); + _objectConfigData->_securityManager->start(); + } } NacosNamingService::~NacosNamingService() { - if (beatReactor != NULL) { - delete beatReactor; - } - beatReactor = NULL; - - if (_tcpNamingServicePoller != NULL) - { - delete _tcpNamingServicePoller; - } - _tcpNamingServicePoller = NULL; - - if (_eventDispatcher != NULL) - { - delete _eventDispatcher; - } - _eventDispatcher = NULL; - - if (serverProxy != NULL) { - delete serverProxy; - } - serverProxy = NULL; - - if (_serverListManager != NULL) { - delete _serverListManager; - } - _serverListManager = NULL; - - if (_httpDelegate != NULL) { - delete _httpDelegate; - } - _httpDelegate = NULL; - - if (_httpCli != NULL) { - delete _httpCli; - } - _httpCli = NULL; - - if (_appConfigMgr != NULL) - { - delete _appConfigMgr; - } - _appConfigMgr = NULL; + delete _objectConfigData; } void NacosNamingService::registerInstance @@ -141,10 +96,10 @@ void NacosNamingService::registerInstance beatInfo.metadata = instance.metadata; beatInfo.scheduled = false; - beatReactor->addBeatInfo(NamingUtils::getGroupedName(serviceName, groupName), beatInfo); + _objectConfigData->_beatReactor->addBeatInfo(NamingUtils::getGroupedName(serviceName, groupName), beatInfo); } - serverProxy->registerService(NamingUtils::getGroupedName(serviceName, groupName), groupName, instance); + _objectConfigData->_serverProxy->registerService(NamingUtils::getGroupedName(serviceName, groupName), groupName, instance); } void NacosNamingService::deregisterInstance @@ -198,8 +153,8 @@ void NacosNamingService::deregisterInstance const NacosString &groupName, Instance &instance ) throw(NacosException) { - beatReactor->removeBeatInfo(NamingUtils::getGroupedName(serviceName, groupName), instance.ip, instance.port); - serverProxy->deregisterService(NamingUtils::getGroupedName(serviceName, groupName), instance); + _objectConfigData->_beatReactor->removeBeatInfo(NamingUtils::getGroupedName(serviceName, groupName), instance.ip, instance.port); + _objectConfigData->_serverProxy->deregisterService(NamingUtils::getGroupedName(serviceName, groupName), instance); } list NacosNamingService::getAllInstances @@ -236,7 +191,7 @@ list NacosNamingService::getAllInstances ServiceInfo serviceInfo; //TODO:cache and failover NacosString clusterString = ParamUtils::Implode(clusters); - NacosString result = serverProxy->queryList(serviceName, clusterString, 0/*What should be filled in UDPPort??*/, + NacosString result = _objectConfigData->_serverProxy->queryList(serviceName, clusterString, 0/*What should be filled in UDPPort??*/, false); serviceInfo = JSON::JsonStr2ServiceInfo(result); list hostlist = serviceInfo.getHosts(); @@ -280,10 +235,10 @@ void NacosNamingService::subscribe { NacosString clusterName = ParamUtils::Implode(clusters); NacosString groupedName = NamingUtils::getGroupedName(serviceName, groupName); - if (!_eventDispatcher->addListener(groupedName, clusterName, listener)){ + if (!_objectConfigData->_eventDispatcher->addListener(groupedName, clusterName, listener)){ return;//The listener is already listening to the service specified, no need to add to the polling list } - _tcpNamingServicePoller->addPollItem(serviceName, groupName, clusterName); + _objectConfigData->_tcpNamingServicePoller->addPollItem(serviceName, groupName, clusterName); } @@ -297,12 +252,12 @@ void NacosNamingService::unsubscribe( NacosString clusterName = ParamUtils::Implode(clusters); NacosString groupedName = NamingUtils::getGroupedName(serviceName, groupName); int remainingListener; - if (!_eventDispatcher->removeListener(groupedName, clusterName, listener, remainingListener)) { + if (!_objectConfigData->_eventDispatcher->removeListener(groupedName, clusterName, listener, remainingListener)) { return;//The listener is not in the list or it is already removed } if (remainingListener == 0) { //Since there's no more listeners listening to this service, remove it from the polling list - _tcpNamingServicePoller->removePollItem(serviceName, groupName, clusterName); + _objectConfigData->_tcpNamingServicePoller->removePollItem(serviceName, groupName, clusterName); } } @@ -334,11 +289,11 @@ void NacosNamingService::unsubscribe(const NacosString &serviceName, EventListen } ListView NacosNamingService::getServiceList(int pageNo, int pageSize) throw (NacosException) { - return serverProxy->getServiceList(pageNo, pageSize, Constants::DEFAULT_GROUP); + return _objectConfigData->_serverProxy->getServiceList(pageNo, pageSize, Constants::DEFAULT_GROUP); } ListView NacosNamingService::getServiceList(int pageNo, int pageSize, const NacosString &groupName) throw (NacosException){ - return serverProxy->getServiceList(pageNo, pageSize, groupName); + return _objectConfigData->_serverProxy->getServiceList(pageNo, pageSize, groupName); } list NacosNamingService::getInstanceWithPredicate diff --git a/src/naming/NacosNamingService.h b/src/naming/NacosNamingService.h index 1ef67c1..49e866a 100644 --- a/src/naming/NacosNamingService.h +++ b/src/naming/NacosNamingService.h @@ -10,18 +10,12 @@ #include "src/http/IHttpCli.h" #include "NacosString.h" #include "Properties.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ class NacosNamingService : public NamingService { private: - HttpDelegate *_httpDelegate = NULL; - NamingProxy *serverProxy = NULL; - BeatReactor *beatReactor = NULL; - EventDispatcher *_eventDispatcher = NULL; - TcpNamingServicePoller *_tcpNamingServicePoller = NULL; - AppConfigManager *_appConfigMgr = NULL; - IHttpCli *_httpCli = NULL; - ServerListManager *_serverListManager = NULL; + ObjectConfigData *_objectConfigData; NacosNamingService(); @@ -29,14 +23,7 @@ class NacosNamingService : public NamingService { NacosString logName; public: - NacosNamingService(HttpDelegate *httpDelegate, - IHttpCli *httpCli, - NamingProxy *serverProxy, - BeatReactor *beatReactor, - EventDispatcher *eventDispatcher, - TcpNamingServicePoller *tcpNamingServicePoller, - AppConfigManager *appConfigManager, - ServerListManager *serverListManager); + NacosNamingService(ObjectConfigData *objectConfigData); ~NacosNamingService(); @@ -116,17 +103,17 @@ class NacosNamingService : public NamingService { std::list getInstanceWithPredicate(const NacosString &serviceName, nacos::naming::selectors::Selector *predicate) throw(NacosException); - IHttpCli *getHttpCli() const { return _httpCli; }; + IHttpCli *getHttpCli() const { return _objectConfigData->_httpCli; }; - NamingProxy *getServerProxy() const { return serverProxy; }; + NamingProxy *getServerProxy() const { return _objectConfigData->_serverProxy; }; - BeatReactor *getBeatReactor() const { return beatReactor; }; + BeatReactor *getBeatReactor() const { return _objectConfigData->_beatReactor; }; - void setHttpCli(IHttpCli *httpCli) { this->_httpCli = httpCli; }; + void setHttpCli(IHttpCli *httpCli) { this->_objectConfigData->_httpCli = httpCli; }; - void setServerProxy(NamingProxy *_namingProxy) { this->serverProxy = _namingProxy; }; + void setServerProxy(NamingProxy *_namingProxy) { this->_objectConfigData->_serverProxy = _namingProxy; }; - void setBeatReactor(BeatReactor *_beatReactor) { this->beatReactor = beatReactor; }; + void setBeatReactor(BeatReactor *_beatReactor) { this->_objectConfigData->_beatReactor = _beatReactor; }; }; }//namespace nacos diff --git a/src/naming/NamingProxy.cpp b/src/naming/NamingProxy.cpp index 01e9931..fb7265b 100644 --- a/src/naming/NamingProxy.cpp +++ b/src/naming/NamingProxy.cpp @@ -6,7 +6,7 @@ #include "src/utils/NetUtils.h" #include "utils/RandomUtils.h" #include "src/json/JSON.h" -#include "src/http/httpStatCode.h" +#include "src/http/HttpStatus.h" #include "Debug.h" #include "NacosExceptions.h" @@ -16,30 +16,24 @@ namespace nacos{ ListView NamingProxy::nullResult; -NamingProxy::NamingProxy(HttpDelegate *httpDelegate, ServerListManager *_serverListManager, AppConfigManager *_appConfigManager) { +NamingProxy::NamingProxy(ObjectConfigData *objectConfigData) { + _objectConfigData = objectConfigData; log_debug("NamingProxy Constructor:\n" "namespace:%s, endpoint:%s, Servers:%s\n", - _serverListManager->getNamespace().c_str(), _serverListManager->getEndpoint().c_str(), - _serverListManager->toString().c_str()); - serverListManager = _serverListManager; - _httpDelegate = httpDelegate; - appConfigManager = _appConfigManager; + objectConfigData->_serverListManager->getNamespace().c_str(), objectConfigData->_serverListManager->getEndpoint().c_str(), + objectConfigData->_serverListManager->toString().c_str()); serverPort = "8848"; - _http_req_timeout = atoi(appConfigManager->get(PropertyKeyConst::HTTP_REQ_TIMEOUT).c_str()); - if (serverListManager->getServerCount() == 1) { - nacosDomain = serverListManager->getServerList().begin()->getCompleteAddress(); + if (objectConfigData->_serverListManager->getServerCount() == 1) { + nacosDomain = objectConfigData->_serverListManager->getServerList().begin()->getCompleteAddress(); } - log_debug("The serverlist:%s\n", _serverListManager->toString().c_str()); + log_debug("The serverlist:%s\n", objectConfigData->_serverListManager->toString().c_str()); nullResult.setCount(0); - _hb_fail_wait = atoi(appConfigManager->get(PropertyKeyConst::HB_FAIL_WAIT_TIME).c_str()); + _hb_fail_wait = atoi(objectConfigData->_appConfigManager->get(PropertyKeyConst::HB_FAIL_WAIT_TIME).c_str()); } NamingProxy::~NamingProxy() { - _httpDelegate = NULL; - appConfigManager = NULL; - serverListManager = NULL; } void NamingProxy::registerService(const NacosString &serviceName, const NacosString &groupName, @@ -93,9 +87,10 @@ NacosString NamingProxy::queryList(const NacosString &serviceName, const NacosSt NacosString NamingProxy::reqAPI(const NacosString &api, list ¶ms, int method) throw(NacosException) { - list servers = serverListManager->getServerList(); + ServerListManager *_serverListManager = _objectConfigData->_serverListManager; + list servers = _serverListManager->getServerList(); - if (serverListManager->getServerCount() == 0) { + if (_serverListManager->getServerCount() == 0) { throw NacosException(NacosException::NO_SERVER_AVAILABLE, "no server available"); } @@ -107,7 +102,7 @@ NamingProxy::reqAPI(const NacosString &api, list ¶ms, int meth log_debug("selected_server:%d\n", selectedServer); for (size_t i = 0; i < servers.size(); i++) { - NacosServerInfo server = ParamUtils::getNthElem(servers, selectedServer); + const NacosServerInfo &server = ParamUtils::getNthElem(servers, selectedServer); log_debug("Trying to access server:%s\n", server.toString().c_str()); try { return callServer(api, params, server.getCompleteAddress(), method); @@ -124,7 +119,7 @@ NamingProxy::reqAPI(const NacosString &api, list ¶ms, int meth selectedServer = (selectedServer + 1) % servers.size(); } - throw NacosException(NacosException::ALL_SERVERS_TRIED_AND_FAILED, "failed to req API:" + api + " after all servers(" + serverListManager->toString() + + throw NacosException(NacosException::ALL_SERVERS_TRIED_AND_FAILED, "failed to req API:" + api + " after all servers(" + _serverListManager->toString() + ") tried: " + errmsg); } @@ -139,7 +134,7 @@ NamingProxy::reqAPI(const NacosString &api, list ¶ms, int meth } } - throw NacosException(NacosException::ALL_SERVERS_TRIED_AND_FAILED, "failed to req API:/api/" + api + " after all servers(" + serverListManager->toString() + + throw NacosException(NacosException::ALL_SERVERS_TRIED_AND_FAILED, "failed to req API:/api/" + api + " after all servers(" + _serverListManager->toString() + ") tried: " + errmsg); } @@ -168,13 +163,15 @@ NacosString NamingProxy::callServer } //TODO:http/https implementation - requestUrl = "http://" + requestUrl + api; + requestUrl = requestUrl + api; HttpResult requestRes; list headers; headers = builderHeaders(); + HttpDelegate *_httpDelegate = _objectConfigData->_httpDelegate; try { + long _http_req_timeout = _objectConfigData->_appConfigManager->getServeReqTimeout(); switch (method) { case IHttpCli::GET: requestRes = _httpDelegate->httpGet(requestUrl, headers, params, UtilAndComs::ENCODING, @@ -200,11 +197,11 @@ NacosString NamingProxy::callServer throw NacosException(NacosException::SERVER_ERROR, errMsg); } - if (requestRes.code == HTTP_OK) { + if (requestRes.code == HttpStatus::HTTP_OK) { return requestRes.content; } - if (requestRes.code == HTTP_NOT_MODIFIED) { + if (requestRes.code == HttpStatus::HTTP_NOT_MODIFIED) { return NULLSTR; } //TODO:Metrics & Monitoring @@ -215,7 +212,7 @@ NacosString NamingProxy::callServer } inline NacosString NamingProxy::getNamespaceId() { - return appConfigManager->get(PropertyKeyConst::NAMESPACE); + return _objectConfigData->_appConfigManager->get(PropertyKeyConst::NAMESPACE); } list NamingProxy::builderHeaders() { diff --git a/src/naming/NamingProxy.h b/src/naming/NamingProxy.h index e8724fc..cae621a 100644 --- a/src/naming/NamingProxy.h +++ b/src/naming/NamingProxy.h @@ -11,14 +11,13 @@ #include "src/server/ServerListManager.h" #include "naming/ListView.h" #include "naming/ServiceInfo2.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ class NamingProxy { private: NacosString serverPort; - HttpDelegate *_httpDelegate = NULL; - ServerListManager *serverListManager; - AppConfigManager *appConfigManager; + ObjectConfigData *_objectConfigData; NacosString nacosDomain; @@ -36,12 +35,11 @@ class NamingProxy { std::list builderHeaders(); - long _http_req_timeout; long _hb_fail_wait;//Time to wait when a heartbeat request fails (in ms) static ListView nullResult; public: - NamingProxy(HttpDelegate *httpDelegate, ServerListManager *serverListManager, AppConfigManager *appConfigManager); + NamingProxy(ObjectConfigData *objectConfigData); ~NamingProxy(); diff --git a/src/naming/beat/BeatReactor.cpp b/src/naming/beat/BeatReactor.cpp index 26f1b5a..53169cf 100644 --- a/src/naming/beat/BeatReactor.cpp +++ b/src/naming/beat/BeatReactor.cpp @@ -49,7 +49,7 @@ void *BeatReactor::beatMaster(void *param) { void BeatReactor::addBeatInfo(const NacosString &serviceName, BeatInfo &beatInfo) { NacosString beatInfoStr = beatInfo.toString(); log_info("[BEAT] adding beat: %s to beat map.", beatInfoStr.c_str()); - BeatTask *beattask = new BeatTask(beatInfo, _namingProxy, this); + BeatTask *beattask = new BeatTask(beatInfo, _objectConfigData); NacosString beatKey = buildKey(serviceName, beatInfo.ip, beatInfo.port); beattask->setTaskName(beatKey); { diff --git a/src/naming/beat/BeatReactor.h b/src/naming/beat/BeatReactor.h index ebb7233..0015fea 100644 --- a/src/naming/beat/BeatReactor.h +++ b/src/naming/beat/BeatReactor.h @@ -12,11 +12,12 @@ #include "BeatTask.h" #include "Constants.h" #include "utils/UtilAndComs.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ class BeatReactor { private: - NamingProxy *_namingProxy; + ObjectConfigData *_objectConfigData; int _threadCount; ThreadPool *_threadPool; Thread *_beatMaster; @@ -32,15 +33,15 @@ class BeatReactor { long getClientBeatInterval() { return _clientBeatInterval; }; - BeatReactor(NamingProxy *namingProxy, int threadCount) - : _namingProxy(namingProxy), _threadCount(threadCount), _beatInfoLock(), _stop(true), + BeatReactor(ObjectConfigData *objectConfigData, int threadCount) + : _objectConfigData(objectConfigData), _threadCount(threadCount), _beatInfoLock(), _stop(true), _clientBeatInterval(5 * 1000) { _threadPool = new ThreadPool("HeartbeatDaemonPool", _threadCount); _beatMaster = new Thread("BeatMaster", beatMaster, this); }; - BeatReactor(NamingProxy *namingProxy) - : _namingProxy(namingProxy), _threadCount(UtilAndComs::DEFAULT_CLIENT_BEAT_THREAD_COUNT), _beatInfoLock(), + BeatReactor(ObjectConfigData *objectConfigData) + : _objectConfigData(objectConfigData), _threadCount(UtilAndComs::DEFAULT_CLIENT_BEAT_THREAD_COUNT), _beatInfoLock(), _stop(true), _clientBeatInterval(5 * 1000) { _threadPool = new ThreadPool("HeartbeatDaemonPool", _threadCount); _beatMaster = new Thread("BeatMaster", beatMaster, this); diff --git a/src/naming/beat/BeatTask.cpp b/src/naming/beat/BeatTask.cpp index be72c2e..c8f8c4e 100644 --- a/src/naming/beat/BeatTask.cpp +++ b/src/naming/beat/BeatTask.cpp @@ -7,8 +7,8 @@ using namespace std; namespace nacos{ -BeatTask::BeatTask(BeatInfo &beatInfo, NamingProxy *namingProxy, BeatReactor *beatReactor) - : _beatInfo(beatInfo), _namingProxy(namingProxy), _beatReactor(beatReactor), _scheduled(false) { +BeatTask::BeatTask(BeatInfo &beatInfo, ObjectConfigData *objectConfigData) + : _beatInfo(beatInfo), _objectConfigData(objectConfigData), _scheduled(false) { incRef(); }; @@ -21,8 +21,8 @@ void BeatTask::setBeatInfo(const BeatInfo &beatInfo) { } void BeatTask::run() { - long newInterval = _namingProxy->sendBeat(_beatInfo); - _beatReactor->setClientBeatInterval(newInterval); + long newInterval = _objectConfigData->_serverProxy->sendBeat(_beatInfo); + _objectConfigData->_beatReactor->setClientBeatInterval(newInterval); setScheduled(false); int refcount = decRef(); if (refcount == 0) { diff --git a/src/naming/beat/BeatTask.h b/src/naming/beat/BeatTask.h index 8dd97cb..167e020 100644 --- a/src/naming/beat/BeatTask.h +++ b/src/naming/beat/BeatTask.h @@ -7,6 +7,7 @@ #include "src/thread/ThreadPool.h" #include "thread/AtomicInt.h" #include "Debug.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ class BeatReactor; @@ -14,12 +15,11 @@ class BeatReactor; class BeatTask : public Task { private: BeatInfo _beatInfo; - NamingProxy *_namingProxy; - BeatReactor *_beatReactor; + ObjectConfigData *_objectConfigData; AtomicInt _refCount; bool _scheduled; public: - BeatTask(BeatInfo &beatInfo, NamingProxy *namingProxy, BeatReactor *beatReactor); + BeatTask(BeatInfo &beatInfo, ObjectConfigData *objectConfigData); ~BeatTask(); diff --git a/src/naming/subscribe/TcpNamingServicePoller.cpp b/src/naming/subscribe/TcpNamingServicePoller.cpp index 072cb59..1c6b1d1 100644 --- a/src/naming/subscribe/TcpNamingServicePoller.cpp +++ b/src/naming/subscribe/TcpNamingServicePoller.cpp @@ -6,13 +6,11 @@ using namespace std; namespace nacos{ -TcpNamingServicePoller::TcpNamingServicePoller(EventDispatcher *eventDispatcher, NamingProxy *namingProxy, AppConfigManager *appConfigManager) +TcpNamingServicePoller::TcpNamingServicePoller(ObjectConfigData *objectConfigData) { - _eventDispatcher = eventDispatcher; - _namingProxy = namingProxy; - _appConfigMgr = appConfigManager; + _objectConfigData = objectConfigData; _pollingThread = new Thread("NamingServicePoller", pollingThreadFunc, (void*)this); - _pollingInterval = atoi(_appConfigMgr->get(PropertyKeyConst::TCP_NAMING_POLL_INTERVAL).c_str()); + _pollingInterval = atoi(_objectConfigData->_appConfigManager->get(PropertyKeyConst::TCP_NAMING_POLL_INTERVAL).c_str()); _started = false; } @@ -21,9 +19,6 @@ TcpNamingServicePoller::~TcpNamingServicePoller() if (_started) { stop(); } - _eventDispatcher = NULL; - _namingProxy = NULL; - _appConfigMgr = NULL; if (_pollingThread != NULL) { delete _pollingThread; @@ -110,8 +105,8 @@ void *TcpNamingServicePoller::pollingThreadFunc(void *parm) NacosString result; try { - result = thisObj->_namingProxy->queryList(it->second.serviceName, it->second.clusters, 0, - false); + result = thisObj->_objectConfigData->_serverProxy->queryList( + it->second.serviceName, it->second.clusters, 0,false); } catch (NacosException &e) { //no server available or all servers tried but failed @@ -140,7 +135,7 @@ void *TcpNamingServicePoller::pollingThreadFunc(void *parm) if (changeAdvice.modified || changeAdvice.added || changeAdvice.removed) { //asm volatile("int $3"); changeAdvice.newServiceInfo = serviceInfo; - thisObj->_eventDispatcher->notifyDirectly(changeAdvice); + thisObj->_objectConfigData->_eventDispatcher->notifyDirectly(changeAdvice); } thisObj->serviceInfoList[key] = serviceInfo;//update local service info to the new one } diff --git a/src/naming/subscribe/TcpNamingServicePoller.h b/src/naming/subscribe/TcpNamingServicePoller.h index 43ad07f..1a4cc73 100644 --- a/src/naming/subscribe/TcpNamingServicePoller.h +++ b/src/naming/subscribe/TcpNamingServicePoller.h @@ -9,6 +9,7 @@ #include "src/thread/Thread.h" #include "src/naming/NamingProxy.h" #include "EventDispatcher.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ struct PollingData @@ -24,9 +25,7 @@ class TcpNamingServicePoller Thread *_pollingThread = NULL; int _pollingInterval;//In ms bool _started; - EventDispatcher *_eventDispatcher = NULL; - NamingProxy *_namingProxy = NULL; - AppConfigManager *_appConfigMgr = NULL; + ObjectConfigData *_objectConfigData; TcpNamingServicePoller(); @@ -36,7 +35,7 @@ class TcpNamingServicePoller std::map pollingList; std::map serviceInfoList; public: - TcpNamingServicePoller(EventDispatcher *eventDispatcher, NamingProxy *namingProxy, AppConfigManager *appConfigManager); + TcpNamingServicePoller(ObjectConfigData *objectConfigData); bool addPollItem(const NacosString &serviceName, const NacosString &groupName, const NacosString &clusters); bool removePollItem(const NacosString &serviceName, const NacosString &groupName, const NacosString &clusters); void start(); diff --git a/src/security/SecurityManager.cpp b/src/security/SecurityManager.cpp new file mode 100644 index 0000000..a30dd78 --- /dev/null +++ b/src/security/SecurityManager.cpp @@ -0,0 +1,143 @@ +// +// Created by liuhanyu on 2020/11/28. +// + +#include "SecurityManager.h" +#include "src/json/JSON.h" +#include "utils/RandomUtils.h" +#include "src/utils/TimeUtils.h" + +using namespace std; +namespace nacos { +SecurityManager::SecurityManager(ObjectConfigData *objectConfigData) { + _objectConfigData = objectConfigData; + _started = false; + _tokenRefreshThread = new Thread("TokenRefreshThread", tokenRefreshThreadFunc, (void*)this); +} +void SecurityManager::doLogin(const NacosString &serverAddr) throw(NacosException, NetworkException) { + //TODO:refactor string constants + NacosString url = serverAddr + "/" + Constants::DEFAULT_CONTEXT_PATH + "/v1/auth/users/login"; + list headers; + list paramValues; + + const NacosString &username = _objectConfigData->_appConfigManager->get(PropertyKeyConst::AUTH_USERNAME); + const NacosString &password = _objectConfigData->_appConfigManager->get(PropertyKeyConst::AUTH_PASSWORD); + + paramValues.push_back("username"); + paramValues.push_back(username); + paramValues.push_back("password"); + paramValues.push_back(password); + + HttpResult result = _objectConfigData->_httpCli->httpPost(url, headers, paramValues, NULLSTR, 3000); + + _accessToken = JSON::Json2AccessToken(result.content); +} + +void SecurityManager::login() throw (NacosException) { + WriteGuard writeGuard(_rwLock); + list serversToTry = _objectConfigData->_serverListManager->getServerList(); + size_t nr_servers = serversToTry.size(); + if (nr_servers == 0) { + throw NacosException(NacosException::NO_SERVER_AVAILABLE, "No available server when getting access token"); + } + + size_t start = 0; + + if (nr_servers > 1) { + start = RandomUtils::random(0, nr_servers - 1); + } + + for (size_t nr_tries = 0; nr_tries < nr_servers; nr_tries++) { + const NacosServerInfo &curServer = ParamUtils::getNthElem(serversToTry, nr_tries + start % nr_servers); + NacosString serverAddr = curServer.getCompleteAddress(); + try { + //the method will throw if there's something wrong(e.g.: network problem) + doLogin(serverAddr); + } catch (NetworkException &e) { + //continue to try next node + continue; + } catch (NacosException &e) { + //for some cases, e.g.:invalid username/password, + //we should throw exception directly since retry on another node will not correct this problem + if (e.errorcode() == NacosException::INVALID_LOGIN_CREDENTIAL) { + throw e; + } + continue; + } + //login succeeded + return; + } + //this is (usually) a network problem, the caller (thread) should handle this + throw NacosException(NacosException::ALL_SERVERS_TRIED_AND_FAILED, "Login failed after all servers are tried"); +} + +NacosString &SecurityManager::getAccessToken() { + ReadGuard _readGuard(_rwLock); + return _accessToken.accessToken; +} + +void SecurityManager::addAccessToken2Req(std::list ¶meter){ + ReadGuard _readGuard(_rwLock); + parameter.push_back("accessToken"); + parameter.push_back(_accessToken.accessToken); +} + +SecurityManager::~SecurityManager() { + stop(); + delete _tokenRefreshThread; + _tokenRefreshThread = NULL; +} + +void SecurityManager::sleepWithRunStatusCheck(long _milliSecsToSleep) { + if (_milliSecsToSleep == 0) { + return; + } + long granularity = 10; + long sleep_start_time = TimeUtils::getCurrentTimeInMs(); + long sleep_end_time = sleep_start_time + _milliSecsToSleep; + while (_started) { + if (TimeUtils::getCurrentTimeInMs() >= sleep_end_time) { + break; + } + sleep(granularity); + } +} + +void *SecurityManager::tokenRefreshThreadFunc(void *param) { + SecurityManager *thisObj = (SecurityManager*)param; + log_debug("In thread SecurityManager::tokenRefreshThreadFunc\n"); + while (thisObj->_started) { + try { + log_debug("Ttl got from nacos server:%ld\n", thisObj->_accessToken.tokenTtl); + thisObj->sleepWithRunStatusCheck(thisObj->_accessToken.tokenTtl * 1000); + log_debug("Trying to login...\n"); + thisObj->login(); + } catch (NacosException &e) { + if (e.errorcode() == NacosException::INVALID_LOGIN_CREDENTIAL) { + throw e;//Invalid login credential, let it crash + } else if (e.errorcode() == NacosException::ALL_SERVERS_TRIED_AND_FAILED) { + sleep(30);//network down, wait for a moment + continue; + } + } + } + return NULL; +} + +void SecurityManager::start() { + if (_started) { + return; + } + + _started = true; + _tokenRefreshThread->start(); +} + +void SecurityManager::stop() { + if (!_started) { + return; + } + _started = false; + _tokenRefreshThread->join(); +} +}//nacos \ No newline at end of file diff --git a/src/security/SecurityManager.h b/src/security/SecurityManager.h new file mode 100644 index 0000000..9dd09f4 --- /dev/null +++ b/src/security/SecurityManager.h @@ -0,0 +1,49 @@ +// +// Created by liuhanyu on 2020/11/28. +// + +#ifndef NACOS_SDK_CPP_SECURITYMANAGER_H +#define NACOS_SDK_CPP_SECURITYMANAGER_H + +#include "src/config/AppConfigManager.h" +#include "src/http/IHttpCli.h" +#include "src/server/ServerListManager.h" +#include "src/factory/ObjectConfigData.h" + +namespace nacos { + +struct AccessToken { + NacosString accessToken; + long tokenTtl; + bool globalAdmin; + long lastRefTime; + AccessToken() { + accessToken = ""; + tokenTtl = 0; + globalAdmin = false; + lastRefTime = 0; + } +}; + +class SecurityManager { +private: + ObjectConfigData *_objectConfigData; + AccessToken _accessToken; + void doLogin(const NacosString &serverAddr) throw(NacosException, NetworkException); + RWLock _rwLock; + volatile bool _started; + static void * tokenRefreshThreadFunc(void *param); + Thread *_tokenRefreshThread; + void sleepWithRunStatusCheck(long _milliSecsToSleep); +public: + SecurityManager(ObjectConfigData *objectConfigData); + ~SecurityManager(); + void login() throw (NacosException); + NacosString &getAccessToken(); + void addAccessToken2Req(std::list ¶meter); + void start(); + void stop(); +}; +} + +#endif //NACOS_SDK_CPP_SECURITYMANAGER_H diff --git a/src/server/NacosServerInfo.h b/src/server/NacosServerInfo.h index 30eef22..6e98405 100644 --- a/src/server/NacosServerInfo.h +++ b/src/server/NacosServerInfo.h @@ -10,8 +10,10 @@ namespace nacos{ //a instance of nacos naming service + class NacosServerInfo { private: + int mode;//1 - http/2 - https NacosString ip; int port; NacosString site; @@ -22,6 +24,19 @@ class NacosServerInfo { NacosString lastRefTimeStr; NacosString key; public: + enum MODE { + mode_http = 1, + mode_http_safe + }; + + int getMode() const { + return mode; + } + + void setMode(int mode) { + NacosServerInfo::mode = mode; + } + const NacosString getIp() const { return ip; } diff --git a/src/server/ServerListManager.cpp b/src/server/ServerListManager.cpp index 4967b87..7854587 100644 --- a/src/server/ServerListManager.cpp +++ b/src/server/ServerListManager.cpp @@ -2,7 +2,6 @@ #include #include "ServerListManager.h" #include "PropertyKeyConst.h" -#include "Parameters.h" #include "utils/ParamUtils.h" #include "Debug.h" #include "src/json/JSON.h" @@ -11,27 +10,52 @@ using namespace std; namespace nacos{ void ServerListManager::addToSrvList(NacosString &address) { - //If the address doesn't contain port, add 8848 as the default port for it - if (address.find(':') == std::string::npos) { + address = ParamUtils::trim(address); + NacosString address_lc = ParamUtils::toLower(address); + if (address_lc.find("http://") == 0 || + address_lc.find("https://") == 0) { + size_t startPos = address.find(':');//4=http,5=https + //use http://someaddress[:port] as server address + NacosString ip = address; + int port = PropertyKeyConst::NACOS_DEFAULT_PORT; + size_t pos = address.find_last_of(':'); + if (pos != 4 && pos != 5) { + NacosString portStr = address.substr(pos + 1); + port = atoi(portStr.c_str()); + ip = address.substr(0, pos); + } NacosServerInfo curServer; - curServer.setKey(address + ":8848"); + curServer.setKey(address); curServer.setAlive(true); - curServer.setIp(address); - //TODO:dynamically read default port, don't use hard-coded value - curServer.setPort(8848); + curServer.setIp(ip); + curServer.setPort(port); curServer.setWeight(1.0); curServer.setAdWeight(1.0); + curServer.setMode(startPos == 4 ? NacosServerInfo::mode_http : NacosServerInfo::mode_http_safe); + serverList.push_back(curServer); + } else if (address.find(':') == std::string::npos) { + //If the address doesn't contain port, add 8848 as the default port for it + NacosServerInfo curServer; + curServer.setKey("http://" + address + ":" + NacosStringOps::valueOf(PropertyKeyConst::NACOS_DEFAULT_PORT)); + curServer.setAlive(true); + curServer.setIp("http://" + address); + curServer.setPort(PropertyKeyConst::NACOS_DEFAULT_PORT); + curServer.setWeight(1.0); + curServer.setAdWeight(1.0); + curServer.setMode(NacosServerInfo::mode_http); serverList.push_back(curServer); } else { + //user specified address & port vector explodedAddress; ParamUtils::Explode(explodedAddress, address, ':'); NacosServerInfo curServer; - curServer.setKey(address); + curServer.setKey("http://" + address); curServer.setAlive(true); - curServer.setIp(explodedAddress[0]); + curServer.setIp("http://" + explodedAddress[0]); curServer.setPort(atoi(explodedAddress[1].c_str())); curServer.setWeight(1.0); curServer.setAdWeight(1.0); + curServer.setMode(NacosServerInfo::mode_http); serverList.push_back(curServer); } } @@ -40,7 +64,6 @@ ServerListManager::ServerListManager(list &fixed) { started = false; isFixed = true; refreshInterval = 30000; - _read_timeout = 3000; for (list::iterator it = fixed.begin(); it != fixed.end(); it++) { addToSrvList(*it); } @@ -63,7 +86,7 @@ NacosString ServerListManager::getCurrentServerAddr() { void ServerListManager::initAll() throw(NacosException) { serverList.clear(); - Properties props = appConfigManager->getAllConfig(); + Properties props = _objectConfigData->_appConfigManager->getAllConfig(); if (props.contains(PropertyKeyConst::SERVER_ADDR)) {//Server address is configured isFixed = true; NacosString server_addr = props[PropertyKeyConst::SERVER_ADDR]; @@ -80,11 +103,17 @@ void ServerListManager::initAll() throw(NacosException) { } isFixed = false; + NacosString endpoint = getEndpoint(); + NacosString endpoint_lc = ParamUtils::toLower(endpoint); + //endpoint doesn't start with http or https prefix, consider it as http + if (!endpoint_lc.find("http://") == 0 && !endpoint_lc.find("https://") == 0) { + endpoint = "http://" + endpoint; + } if (NacosStringOps::isNullStr(getNamespace())) { - addressServerUrl = getEndpoint() + ":" + NacosStringOps::valueOf(getEndpointPort()) + "/" + + addressServerUrl = endpoint + ":" + NacosStringOps::valueOf(getEndpointPort()) + "/" + getContextPath() + "/" + getClusterName(); } else { - addressServerUrl = getEndpoint() + ":" + NacosStringOps::valueOf(getEndpointPort()) + "/" + + addressServerUrl = endpoint + ":" + NacosStringOps::valueOf(getEndpointPort()) + "/" + getContextPath() + "/" + getClusterName() + "?namespace=" + getNamespace(); } @@ -95,12 +124,10 @@ void ServerListManager::initAll() throw(NacosException) { } } -ServerListManager::ServerListManager(HttpDelegate *httpDelegate, AppConfigManager *_appConfigManager) throw(NacosException) { +ServerListManager::ServerListManager(ObjectConfigData *objectConfigData) throw(NacosException) { started = false; - this->_httpDelegate = httpDelegate; - this->appConfigManager = _appConfigManager; - refreshInterval = atoi(appConfigManager->get(PropertyKeyConst::SRVLISTMGR_REFRESH_INTERVAL).c_str()); - _read_timeout = atoi(appConfigManager->get(PropertyKeyConst::SRVLISTMGR_READ_TIMEOUT).c_str()); + _objectConfigData = objectConfigData; + refreshInterval = atoi(_objectConfigData->_appConfigManager->get(PropertyKeyConst::SRVLISTMGR_REFRESH_INTERVAL).c_str()); initAll(); } @@ -114,16 +141,17 @@ list ServerListManager::tryPullServerListFromNacosServer() thr log_debug("nr_servers:%d\n", maxSvrSlot); srand(time(NULL)); + long _read_timeout = _objectConfigData->_appConfigManager->getServeReqTimeout(); NacosString errmsg; for (size_t i = 0; i < serverList.size(); i++) { size_t selectedServer = rand() % maxSvrSlot; - NacosServerInfo server = ParamUtils::getNthElem(serverList, selectedServer); + const NacosServerInfo &server = ParamUtils::getNthElem(serverList, selectedServer); log_debug("selected_server:%d\n", selectedServer); log_debug("Trying to access server:%s\n", server.getCompleteAddress().c_str()); try { - HttpResult serverRes = _httpDelegate->httpGet( - server.getCompleteAddress() + "/" + DEFAULT_CONTEXT_PATH + "/" + PROTOCOL_VERSION + "/" + - GET_SERVERS_PATH, + HttpResult serverRes = _objectConfigData->_httpDelegate->httpGet( + server.getCompleteAddress() + "/" + Constants::DEFAULT_CONTEXT_PATH + "/" + + Constants::PROTOCOL_VERSION + "/" + Constants::GET_SERVERS_PATH, headers, paramValues, NULLSTR, _read_timeout); return JSON::Json2NacosServerInfo(serverRes.content); } @@ -148,8 +176,9 @@ list ServerListManager::pullServerList() throw(NacosException) std::list headers; std::list paramValues; + long _read_timeout = _objectConfigData->_appConfigManager->getServeReqTimeout(); if (!NacosStringOps::isNullStr(addressServerUrl)) { - HttpResult serverRes = _httpDelegate->httpGet(addressServerUrl, headers, paramValues, NULLSTR, + HttpResult serverRes = _objectConfigData->_httpDelegate->httpGet(addressServerUrl, headers, paramValues, NULLSTR, _read_timeout); list explodedServerList; ParamUtils::Explode(explodedServerList, serverRes.content, '\n'); @@ -164,7 +193,7 @@ list ServerListManager::pullServerList() throw(NacosException) curServer.setPort(8848); } else { NacosString ip = it->substr(0, pos); - NacosString port = it->substr(pos); + NacosString port = it->substr(pos + 1); curServer.setIp(ip); curServer.setPort(atoi(port.c_str())); @@ -264,7 +293,7 @@ void ServerListManager::stop() { } NacosString ServerListManager::getContextPath() const { - return appConfigManager->get(PropertyKeyConst::CONTEXT_PATH); + return _objectConfigData->_appConfigManager->get(PropertyKeyConst::CONTEXT_PATH); } ServerListManager::~ServerListManager() { @@ -285,6 +314,7 @@ int ServerListManager::getServerCount() { }; list ServerListManager::getServerList() { + //further optimization could be implemented here if the server list cannot be changed during runtime std::list res; { ReadGuard _readGuard(rwLock); diff --git a/src/server/ServerListManager.h b/src/server/ServerListManager.h index fb5a0af..93f928c 100644 --- a/src/server/ServerListManager.h +++ b/src/server/ServerListManager.h @@ -11,6 +11,7 @@ #include "src/config/AppConfigManager.h" #include "PropertyKeyConst.h" #include "src/thread/RWLock.h" +#include "src/factory/ObjectConfigData.h" namespace nacos{ class ServerListManager { @@ -41,38 +42,35 @@ class ServerListManager { std::list pullServerList() throw(NacosException); - HttpDelegate *_httpDelegate = NULL; - AppConfigManager *appConfigManager = NULL; + ObjectConfigData *_objectConfigData; static NacosString serverListToString(const std::list &serverList); - long _read_timeout; - public: //Cluster info - inline NacosString getClusterName() const { return appConfigManager->get(PropertyKeyConst::CLUSTER_NAME); }; + inline NacosString getClusterName() const { return _objectConfigData->_appConfigManager->get(PropertyKeyConst::CLUSTER_NAME); }; - inline NacosString getEndpoint() const { return appConfigManager->get(PropertyKeyConst::ENDPOINT); }; + inline NacosString getEndpoint() const { return _objectConfigData->_appConfigManager->get(PropertyKeyConst::ENDPOINT); }; - inline int getEndpointPort() const { return atoi(appConfigManager->get(PropertyKeyConst::ENDPOINT_PORT).c_str()); }; + inline int getEndpointPort() const { return atoi(_objectConfigData->_appConfigManager->get(PropertyKeyConst::ENDPOINT_PORT).c_str()); }; inline NacosString getContextPath() const; - inline NacosString getNamespace() const { return appConfigManager->get(PropertyKeyConst::NAMESPACE); }; + inline NacosString getNamespace() const { return _objectConfigData->_appConfigManager->get(PropertyKeyConst::NAMESPACE); }; std::list __debug();//DO NOT use, may be changed without prior notification - HttpDelegate *getHttpDelegate() const { return _httpDelegate; }; + HttpDelegate *getHttpDelegate() const { return _objectConfigData->_httpDelegate; }; - void setHttpDelegate(HttpDelegate *httpDelegate) { this->_httpDelegate = httpDelegate; }; + void setHttpDelegate(HttpDelegate *httpDelegate) { _objectConfigData->_httpDelegate = httpDelegate; }; - AppConfigManager *getAppConfigManager() const { return appConfigManager; }; + AppConfigManager *getAppConfigManager() const { return _objectConfigData->_appConfigManager; }; - void setAppConfigManager(AppConfigManager *_appConfigManager) { this->appConfigManager = _appConfigManager; }; + void setAppConfigManager(AppConfigManager *_appConfigManager) { _objectConfigData->_appConfigManager = _appConfigManager; }; ServerListManager(std::list &fixed); - ServerListManager(HttpDelegate *httpDelegate, AppConfigManager *_appConfigManager) throw(NacosException); + ServerListManager(ObjectConfigData *objectConfigData) throw(NacosException); NacosString getCurrentServerAddr(); diff --git a/src/thread/Thread.h b/src/thread/Thread.h index 569985e..d67a67a 100644 --- a/src/thread/Thread.h +++ b/src/thread/Thread.h @@ -4,7 +4,7 @@ #include #include #include -#include +//#include #include "NacosString.h" #include "Debug.h" @@ -26,6 +26,7 @@ class Thread { NacosString _threadName; pthread_t _thread; ThreadFn _function; + //TODO:thread id pid_t _tid; bool _start; void *_threadData; diff --git a/src/utils/DirUtils.cpp b/src/utils/DirUtils.cpp index 860506e..c90aaa8 100644 --- a/src/utils/DirUtils.cpp +++ b/src/utils/DirUtils.cpp @@ -1,9 +1,15 @@ #include #include -#include #include #include "utils/DirUtils.h" +#if defined(__CYGWIN__) || defined(MS_WINDOWS) +#define PATH_MAX 260 +#else +#include +#endif + + namespace nacos{ NacosString DirUtils::getHome() { struct passwd *pw = getpwuid(getuid()); diff --git a/src/utils/TimeUtils.cpp b/src/utils/TimeUtils.cpp new file mode 100644 index 0000000..3466aa5 --- /dev/null +++ b/src/utils/TimeUtils.cpp @@ -0,0 +1,12 @@ +#include +#include "TimeUtils.h" + +namespace nacos{ +int64_t TimeUtils::getCurrentTimeInMs() { + struct timeval tv; + gettimeofday(&tv, NULL); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +}//namespace nacos diff --git a/src/utils/TimeUtils.h b/src/utils/TimeUtils.h new file mode 100644 index 0000000..f258c11 --- /dev/null +++ b/src/utils/TimeUtils.h @@ -0,0 +1,14 @@ +#ifndef __TIME_UTILS_H_ +#define __TIME_UTILS_H_ + +#include +#include + +namespace nacos{ +class TimeUtils { +public: + static int64_t getCurrentTimeInMs(); +}; +}//namespace nacos + +#endif diff --git a/test/allinone.cpp b/test/allinone.cpp index d9a4e23..837eaf3 100644 --- a/test/allinone.cpp +++ b/test/allinone.cpp @@ -111,6 +111,10 @@ bool testMaintainCreateService(); bool testMaintainUpdateInstance(); +bool testPublishConfigWithHttpPrefix(); + +bool testRemoveKeyBeingWatched(); + TestData testList1[] = TEST_ITEM_START @@ -173,6 +177,8 @@ TEST_ITEM_START TEST_ITEM("MaintainService: testMaintainUpdateService", testMaintainUpdateService) TEST_ITEM("MaintainService: testMaintainCreateService", testMaintainCreateService) TEST_ITEM("MaintainService: testMaintainUpdateInstance", testMaintainUpdateInstance) + TEST_ITEM("Test with address config containing http prefix", testPublishConfigWithHttpPrefix) + TEST_ITEM("Test with address config containing http prefix", testRemoveKeyBeingWatched) TEST_ITEM_END int main() { diff --git a/test/testcase/AssertString.cpp b/test/testcase/AssertString.cpp index 0998c72..a5e8feb 100644 --- a/test/testcase/AssertString.cpp +++ b/test/testcase/AssertString.cpp @@ -1,5 +1,4 @@ #include -#include "Debug.h" #include "NacosString.h" #include "DebugAssertion.h" diff --git a/test/testcase/DebugTest.cpp b/test/testcase/DebugTest.cpp index eb6c0fa..19eef06 100644 --- a/test/testcase/DebugTest.cpp +++ b/test/testcase/DebugTest.cpp @@ -1,4 +1,3 @@ -#include #include "Debug.h" using namespace std; diff --git a/test/testcase/testAppConfigManager.cpp b/test/testcase/testAppConfigManager.cpp index 2f0fed1..456f623 100644 --- a/test/testcase/testAppConfigManager.cpp +++ b/test/testcase/testAppConfigManager.cpp @@ -1,8 +1,6 @@ #include #include "src/config/AppConfigManager.h" #include "PropertyKeyConst.h" -#include "DebugAssertion.h" -#include "Debug.h" #include "utils/DirUtils.h" #include "Constants.h" diff --git a/test/testcase/testCache.cpp b/test/testcase/testCache.cpp index 724dea7..194fc08 100644 --- a/test/testcase/testCache.cpp +++ b/test/testcase/testCache.cpp @@ -1,8 +1,6 @@ #include -#include -#include "src/config/LocalConfigInfoProcessor.h" +#include "src/config/LocalSnapshotManager.h" #include "DebugAssertion.h" -#include "Debug.h" #include "NacosString.h" #include "ResourceGuard.h" @@ -13,17 +11,17 @@ bool testSaveSnapshot() { cout << "in function testSaveSnapshot" << endl; Properties props; AppConfigManager *appConfigManager = new AppConfigManager(props); - LocalConfigInfoProcessor *localConfigInfoProcessor = new LocalConfigInfoProcessor(appConfigManager); + LocalSnapshotManager *localSnapshotManager = new LocalSnapshotManager(appConfigManager); ResourceGuard __guardCfg(appConfigManager); - ResourceGuard __guardCfgProcessor(localConfigInfoProcessor); + ResourceGuard __guardCfgProcessor(localSnapshotManager); - localConfigInfoProcessor->cleanAllSnapshot(); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", + localSnapshotManager->cleanAllSnapshot(); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", "ConfigName=Value for FrontTenant"); - NacosString content = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); + NacosString content = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); SHOULD_BE_TRUE(content == "ConfigName=Value for FrontTenant", "Saved snapshot, read it again, should be the same"); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "ConfigName=Value"); - content = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "ConfigName=Value"); + content = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); SHOULD_BE_TRUE(content == "ConfigName=Value", "Saved snapshot(No tenant), read it again, should be the same"); return true; } @@ -32,34 +30,34 @@ bool testCleanTestenvCacheAndGetTestenv() { cout << "in function testCleanTestenvCacheAndGetTestenv" << endl; Properties props; AppConfigManager *appConfigManager = new AppConfigManager(props); - LocalConfigInfoProcessor *localConfigInfoProcessor = new LocalConfigInfoProcessor(appConfigManager); + LocalSnapshotManager *localSnapshotManager = new LocalSnapshotManager(appConfigManager); ResourceGuard __guardCfg(appConfigManager); - ResourceGuard __guardCfgProcessor(localConfigInfoProcessor); - localConfigInfoProcessor->cleanAllSnapshot(); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", + ResourceGuard __guardCfgProcessor(localSnapshotManager); + localSnapshotManager->cleanAllSnapshot(); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", "Value for FrontTenant&Testenv"); - localConfigInfoProcessor->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant", + localSnapshotManager->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant", "Value for FrontTenant&Prodenv"); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Testenv"); - localConfigInfoProcessor->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Prodenv"); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Testenv"); + localSnapshotManager->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Prodenv"); - NacosString cntfrontEndTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", + NacosString cntfrontEndTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); - NacosString cntPrdFrontEnd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", + NacosString cntPrdFrontEnd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); - NacosString cntTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); - NacosString cntPrd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); + NacosString cntTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); + NacosString cntPrd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); SHOULD_BE_TRUE(cntfrontEndTest == "Value for FrontTenant&Testenv", "Check settings for FrontTenant&Testenv"); SHOULD_BE_TRUE(cntPrdFrontEnd == "Value for FrontTenant&Prodenv", "Check settings for FrontTenant&Prodenv"); SHOULD_BE_TRUE(cntTest == "Value for Testenv", "Check settings for Testenv"); SHOULD_BE_TRUE(cntPrd == "Value for Prodenv", "Check settings for Prodenv"); - localConfigInfoProcessor->cleanEnvSnapshot("Testenv"); - cntfrontEndTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); - cntPrdFrontEnd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); - cntTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); - cntPrd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); + localSnapshotManager->cleanEnvSnapshot("Testenv"); + cntfrontEndTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); + cntPrdFrontEnd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); + cntTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); + cntPrd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); SHOULD_BE_TRUE(cntfrontEndTest == "", "Testenv removed, Check settings for FrontTenant&Testenv"); SHOULD_BE_TRUE(cntPrdFrontEnd == "Value for FrontTenant&Prodenv", @@ -73,34 +71,34 @@ bool testCleanPrdCacheAndGetPrdenv() { cout << "in function testCleanPrdCacheAndGetPrdenv" << endl; Properties props; AppConfigManager *appConfigManager = new AppConfigManager(props); - LocalConfigInfoProcessor *localConfigInfoProcessor = new LocalConfigInfoProcessor(appConfigManager); + LocalSnapshotManager *localSnapshotManager = new LocalSnapshotManager(appConfigManager); ResourceGuard __guardCfg(appConfigManager); - ResourceGuard __guardCfgProcessor(localConfigInfoProcessor); - localConfigInfoProcessor->cleanAllSnapshot(); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", + ResourceGuard __guardCfgProcessor(localSnapshotManager); + localSnapshotManager->cleanAllSnapshot(); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", "Value for FrontTenant&Testenv"); - localConfigInfoProcessor->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant", + localSnapshotManager->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant", "Value for FrontTenant&Prodenv"); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Testenv"); - localConfigInfoProcessor->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Prodenv"); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Testenv"); + localSnapshotManager->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Prodenv"); - NacosString cntfrontEndTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", + NacosString cntfrontEndTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); - NacosString cntPrdFrontEnd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", + NacosString cntPrdFrontEnd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); - NacosString cntTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); - NacosString cntPrd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); + NacosString cntTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); + NacosString cntPrd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); SHOULD_BE_TRUE(cntfrontEndTest == "Value for FrontTenant&Testenv", "Check settings for FrontTenant&Testenv"); SHOULD_BE_TRUE(cntPrdFrontEnd == "Value for FrontTenant&Prodenv", "Check settings for FrontTenant&Prodenv"); SHOULD_BE_TRUE(cntTest == "Value for Testenv", "Check settings for Testenv"); SHOULD_BE_TRUE(cntPrd == "Value for Prodenv", "Check settings for Prodenv"); - localConfigInfoProcessor->cleanEnvSnapshot("Prodenv"); - cntfrontEndTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); - cntPrdFrontEnd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); - cntTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); - cntPrd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); + localSnapshotManager->cleanEnvSnapshot("Prodenv"); + cntfrontEndTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); + cntPrdFrontEnd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); + cntTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); + cntPrd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); SHOULD_BE_TRUE(cntfrontEndTest == "Value for FrontTenant&Testenv", "Prodenv removed, Check settings for FrontTenant&Testenv"); @@ -114,34 +112,34 @@ bool testCleanAllCache() { cout << "in function testCleanAllCache" << endl; Properties props; AppConfigManager *appConfigManager = new AppConfigManager(props); - LocalConfigInfoProcessor *localConfigInfoProcessor = new LocalConfigInfoProcessor(appConfigManager); + LocalSnapshotManager *localSnapshotManager = new LocalSnapshotManager(appConfigManager); ResourceGuard __guardCfg(appConfigManager); - ResourceGuard __guardCfgProcessor(localConfigInfoProcessor); - localConfigInfoProcessor->cleanAllSnapshot(); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", + ResourceGuard __guardCfgProcessor(localSnapshotManager); + localSnapshotManager->cleanAllSnapshot(); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant", "Value for FrontTenant&Testenv"); - localConfigInfoProcessor->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant", + localSnapshotManager->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant", "Value for FrontTenant&Prodenv"); - localConfigInfoProcessor->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Testenv"); - localConfigInfoProcessor->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Prodenv"); + localSnapshotManager->saveSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Testenv"); + localSnapshotManager->saveSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR, "Value for Prodenv"); - NacosString cntfrontEndTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", + NacosString cntfrontEndTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); - NacosString cntPrdFrontEnd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", + NacosString cntPrdFrontEnd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); - NacosString cntTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); - NacosString cntPrd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); + NacosString cntTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); + NacosString cntPrd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); SHOULD_BE_TRUE(cntfrontEndTest == "Value for FrontTenant&Testenv", "Check settings for FrontTenant&Testenv"); SHOULD_BE_TRUE(cntPrdFrontEnd == "Value for FrontTenant&Prodenv", "Check settings for FrontTenant&Prodenv"); SHOULD_BE_TRUE(cntTest == "Value for Testenv", "Check settings for Testenv"); SHOULD_BE_TRUE(cntPrd == "Value for Prodenv", "Check settings for Prodenv"); - localConfigInfoProcessor->cleanAllSnapshot(); - cntfrontEndTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); - cntPrdFrontEnd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); - cntTest = localConfigInfoProcessor->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); - cntPrd = localConfigInfoProcessor->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); + localSnapshotManager->cleanAllSnapshot(); + cntfrontEndTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", "FrontTenant"); + cntPrdFrontEnd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", "FrontTenant"); + cntTest = localSnapshotManager->getSnapshot("Testenv", "DummyData", "BusinessGrp1", NULLSTR); + cntPrd = localSnapshotManager->getSnapshot("Prodenv", "DummyData", "BusinessGrp1", NULLSTR); SHOULD_BE_TRUE(cntfrontEndTest == "", "cleanAllSnapshot(), Check settings for FrontTenant&Testenv"); SHOULD_BE_TRUE(cntPrdFrontEnd == "", "cleanAllSnapshot(), Check settings for FrontTenant&Prodenv"); diff --git a/test/testcase/testDeleteConfig.cpp b/test/testcase/testDeleteConfig.cpp index d6ca5b7..e6550c9 100644 --- a/test/testcase/testDeleteConfig.cpp +++ b/test/testcase/testDeleteConfig.cpp @@ -3,7 +3,6 @@ #include "factory/NacosServiceFactory.h" #include "PropertyKeyConst.h" #include "DebugAssertion.h" -#include "Debug.h" #include "ResourceGuard.h" using namespace std; @@ -13,6 +12,7 @@ bool testDeleteConfig() { cout << "in function testDeleteConfig" << endl; Properties props; props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; + ADD_AUTH_INFO(props); NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); ConfigService *n = factory->CreateConfigService(); @@ -27,7 +27,7 @@ bool testDeleteConfig() { try { bSucc = n->removeConfig(key_s, NULLSTR); } - catch (NacosException e) { + catch (NacosException &e) { cout << "Request failed with curl code:" << e.errorcode() << endl << "Reason:" << e.what() << endl; diff --git a/test/testcase/testDeleteListenedKeys.cpp b/test/testcase/testDeleteListenedKeys.cpp new file mode 100644 index 0000000..0fc34bc --- /dev/null +++ b/test/testcase/testDeleteListenedKeys.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include "factory/NacosServiceFactory.h" +#include "ResourceGuard.h" +#include "listen/Listener.h" +#include "PropertyKeyConst.h" +#include "DebugAssertion.h" +#include "Debug.h" + +using namespace std; +using namespace nacos; + +class MyListener : public Listener { +private: + int num; +public: + MyListener(int num) { + this->num = num; + } + + void receiveConfigInfo(const NacosString &configInfo) { + cout << "===================================" << endl; + cout << "Watcher" << num << endl; + cout << "Watched Key UPDATED:" << configInfo << endl; + cout << "===================================" << endl; + } +}; + +bool testRemoveKeyBeingWatched() { + cout << "in function testListeningKeys" << endl; + Properties props; + props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; + ADD_AUTH_INFO(props); + NacosServiceFactory *factory = new NacosServiceFactory(props); + ResourceGuard _guardFactory(factory); + ConfigService *n = factory->CreateConfigService(); + ResourceGuard _serviceFactory(n); + n->publishConfig("RemovedWhileWatching", NULLSTR, "dummyContent"); + + MyListener *theListener = new MyListener(1); + n->addListener("RemovedWhileWatching", NULLSTR, theListener); + + sleep(2); + cout << "remove key" << endl; + n->removeConfig("RemovedWhileWatching", NULLSTR); + sleep(2); + cout << "set key" << endl; + n->publishConfig("RemovedWhileWatching", NULLSTR, "dummyContent1"); + sleep(2); + cout << "remove key" << endl; + n->removeConfig("RemovedWhileWatching", NULLSTR); + cout << "Hold for 30 secs" << endl; + sleep(30); + n->removeListener("RemovedWhileWatching", NULLSTR, theListener); + cout << "remove listener2" << endl; + cout << "test successful" << endl; + + return true; +} \ No newline at end of file diff --git a/test/testcase/testEndpointWithNamingSvc.cpp b/test/testcase/testEndpointWithNamingSvc.cpp index 7ff1bb4..f64045f 100644 --- a/test/testcase/testEndpointWithNamingSvc.cpp +++ b/test/testcase/testEndpointWithNamingSvc.cpp @@ -24,6 +24,7 @@ bool testEndpointWithNamingProxy() { cout << "yourip:80/endpoints/endpoint0" << endl; cout << "And the content should be a list of ip:port separated with \\n the ip:port group points at a nacos server" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::ENDPOINT] = "127.0.0.1"; configProps[PropertyKeyConst::ENDPOINT_PORT] = "80"; configProps[PropertyKeyConst::CONTEXT_PATH] = "endpoints"; @@ -47,7 +48,7 @@ bool testEndpointWithNamingProxy() { namingSvc->registerInstance(serviceName, instance); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return false; } @@ -62,7 +63,7 @@ bool testEndpointWithNamingProxy() { sleep(1); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return false; } diff --git a/test/testcase/testGetAllInstances.cpp b/test/testcase/testGetAllInstances.cpp index 4818a82..9e6bc17 100644 --- a/test/testcase/testGetAllInstances.cpp +++ b/test/testcase/testGetAllInstances.cpp @@ -21,6 +21,7 @@ using namespace nacos; bool testGetAllInstances() { cout << "in function testGetAllInstances" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; configProps[PropertyKeyConst::NAMESPACE] = "238e832b-d103-44c6-b618-d74da8c38b06"; NacosServiceFactory *factory = new NacosServiceFactory(configProps); @@ -42,7 +43,7 @@ bool testGetAllInstances() { namingSvc->registerInstance(serviceName, instance); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return false; } @@ -78,7 +79,7 @@ bool testGetAllInstances() { sleep(1); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return false; } diff --git a/test/testcase/testGetConfig.cpp b/test/testcase/testGetConfig.cpp index 52a9829..9b384d7 100644 --- a/test/testcase/testGetConfig.cpp +++ b/test/testcase/testGetConfig.cpp @@ -12,6 +12,7 @@ bool testGetConfig() { cout << "in function testGetConfig" << endl; Properties props; props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; + ADD_AUTH_INFO(props); NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); ConfigService *n = factory->CreateConfigService(); @@ -20,7 +21,7 @@ bool testGetConfig() { try { ss = n->getConfig("k", NULLSTR, 1000); } - catch (NacosException e) { + catch (NacosException &e) { cout << "Request failed with curl code:" << e.errorcode() << endl << "Reason:" << e.what() << endl; @@ -35,6 +36,7 @@ bool testGetConfigwithDefaultPort() { cout << "in function testGetConfigwithDefaultPort" << endl; Properties props; props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; + ADD_AUTH_INFO(props); NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); ConfigService *n = factory->CreateConfigService(); @@ -48,6 +50,7 @@ bool testGetConfigwithDefaultPort() { bool testInvalidConfig() { cout << "in function testInvalidConfig" << endl; Properties props; + ADD_AUTH_INFO(props); NacosString ss; try { @@ -57,7 +60,7 @@ bool testInvalidConfig() { ResourceGuard _serviceFactory(n); ss = n->getConfig("k", NULLSTR, 1000); } - catch (NacosException e) { + catch (NacosException &e) { NacosString errmsgShouldBe = "endpoint is blank"; if (errmsgShouldBe == e.what()) { return true; diff --git a/test/testcase/testGetServiceNames.cpp b/test/testcase/testGetServiceNames.cpp index e39c8ce..4836f13 100644 --- a/test/testcase/testGetServiceNames.cpp +++ b/test/testcase/testGetServiceNames.cpp @@ -21,6 +21,7 @@ using namespace nacos; bool testGetServiceNames() { cout << "in function testGetServiceNames" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; NacosServiceFactory *factory = new NacosServiceFactory(configProps); ResourceGuard _guardFactory(factory); @@ -31,7 +32,7 @@ bool testGetServiceNames() { try { res = namingSvc->getServiceList(1, 10); } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while getting service names, raison:" << e.what() << endl; return false; } diff --git a/test/testcase/testInstanceSelector.cpp b/test/testcase/testInstanceSelector.cpp index 0edc1bf..8029d62 100644 --- a/test/testcase/testInstanceSelector.cpp +++ b/test/testcase/testInstanceSelector.cpp @@ -24,6 +24,7 @@ using namespace nacos::naming::selectors; bool testInstanceSelectors() { cout << "in function testInstanceSelectors" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; configProps[PropertyKeyConst::TCP_NAMING_POLL_INTERVAL] = "3000"; @@ -51,7 +52,7 @@ bool testInstanceSelectors() { } res = namingSvc->getInstanceWithPredicate("TestNamingService0", &randomSelector); } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while getting service names, raison:" << e.what() << endl; return false; } @@ -70,6 +71,7 @@ bool testRandomByWeightSelector() cout << "in function testRandomByWeightSelector" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; configProps[PropertyKeyConst::TCP_NAMING_POLL_INTERVAL] = "3000"; @@ -94,7 +96,7 @@ bool testRandomByWeightSelector() namingSvc->registerInstance(serviceName, instance); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return false; } diff --git a/test/testcase/testListenWorker.cpp b/test/testcase/testListenWorker.cpp index bbc6983..ae007e9 100644 --- a/test/testcase/testListenWorker.cpp +++ b/test/testcase/testListenWorker.cpp @@ -29,6 +29,7 @@ bool testAddListener() { cout << "in function testAddListener" << endl; Properties props; props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; + ADD_AUTH_INFO(props); KeyChangeListener *thelistener = new KeyChangeListener(); thelistener->setKey("k"); bool bSucc; @@ -42,7 +43,7 @@ bool testAddListener() { n->addListener("k", NULLSTR, thelistener); bSucc = n->publishConfig("k", NULLSTR, "hahaha"); } - catch (NacosException e) { + catch (NacosException &e) { cout << "Failed to add listener" << endl << "Reason:" << e.what() << endl; diff --git a/test/testcase/testListeningKeys.cpp b/test/testcase/testListeningKeys.cpp index ff49681..2d6e2e6 100644 --- a/test/testcase/testListeningKeys.cpp +++ b/test/testcase/testListeningKeys.cpp @@ -31,6 +31,7 @@ class MyListener : public Listener { bool testListeningKeys() { cout << "in function testListeningKeys" << endl; Properties props; + ADD_AUTH_INFO(props); props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); diff --git a/test/testcase/testListeningKeysWithHttpPrefix.cpp b/test/testcase/testListeningKeysWithHttpPrefix.cpp new file mode 100644 index 0000000..368de18 --- /dev/null +++ b/test/testcase/testListeningKeysWithHttpPrefix.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include "factory/NacosServiceFactory.h" +#include "ResourceGuard.h" +#include "listen/Listener.h" +#include "PropertyKeyConst.h" +#include "DebugAssertion.h" +#include "Debug.h" + +using namespace std; +using namespace nacos; + +class MyListenerHttpPrefix : public Listener { +private: + int num; +public: + MyListenerHttpPrefix(int num) { + this->num = num; + } + + void receiveConfigInfo(const NacosString &configInfo) { + cout << "===================================" << endl; + cout << "Watcher" << num << endl; + cout << "Watched Key UPDATED:" << configInfo << endl; + cout << "===================================" << endl; + } +}; + +bool testListeningKeysWithHttpPrefix() { + cout << "in function testListeningKeysWithHttpPrefix" << endl; + Properties props; + ADD_AUTH_INFO(props); + props[PropertyKeyConst::SERVER_ADDR] = "HttP://127.0.0.1:8848,HtTP://localhost"; + NacosServiceFactory *factory = new NacosServiceFactory(props); + ResourceGuard _guardFactory(factory); + ConfigService *n = factory->CreateConfigService(); + ResourceGuard _serviceFactory(n); + + MyListenerHttpPrefix *theListener = new MyListenerHttpPrefix(1); + MyListenerHttpPrefix *theListener2 = new MyListenerHttpPrefix(2); + MyListenerHttpPrefix *theListener3 = new MyListenerHttpPrefix(3); + n->addListener("dqid", NULLSTR, theListener); + n->addListener("dqid", NULLSTR, theListener2); + n->addListener("dqid", NULLSTR, theListener3); + n->addListener("dqid1", NULLSTR, theListener3); + n->addListener("dqid2", NULLSTR, theListener3); + n->addListener("dqid3", NULLSTR, theListener3); + + for (int i = 10; i < 60; i++) { + NacosString strKey = "dqid" + NacosStringOps::valueOf(i); + n->addListener(strKey, NULLSTR, theListener3); + } + + cout << "Hold for 20 secs" << endl; + sleep(20); + cout << "remove listener" << endl; + n->removeListener("dqid", NULLSTR, theListener); + + cout << "Hold for 20 secs" << endl; + sleep(20); + cout << "remove listener2" << endl; + n->removeListener("dqid", NULLSTR, theListener2); + n->removeListener("dqid", NULLSTR, theListener3); + cout << "test successful" << endl; + + return true; +} \ No newline at end of file diff --git a/test/testcase/testMaintainInstances.cpp b/test/testcase/testMaintainInstances.cpp index b89b3b7..d25a8f3 100644 --- a/test/testcase/testMaintainInstances.cpp +++ b/test/testcase/testMaintainInstances.cpp @@ -17,6 +17,7 @@ using namespace nacos; bool testMaintainUpdateInstance() { cout << "in function testMaintainUpdateInstance" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; NacosServiceFactory *factory = new NacosServiceFactory(configProps); ResourceGuard _guardFactory(factory); @@ -53,7 +54,7 @@ bool testMaintainUpdateInstance() { } catch (exception &ignore) { /*We may come across service not exist exception, just ignore*/ } return true; } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while testing, raison:" << e.what() << endl; return false; } diff --git a/test/testcase/testMaintainServices.cpp b/test/testcase/testMaintainServices.cpp index 677310e..fdd0cef 100644 --- a/test/testcase/testMaintainServices.cpp +++ b/test/testcase/testMaintainServices.cpp @@ -17,6 +17,7 @@ using namespace nacos; bool testMaintainGetService() { cout << "in function testMaintainGetService" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; NacosServiceFactory *factory = new NacosServiceFactory(configProps); ResourceGuard _guardFactory(factory); @@ -32,7 +33,7 @@ bool testMaintainGetService() { cout << "service name got from server:" << res.getName() << endl; SHOULD_BE_TRUE(res.getName().compare("MaintainTestService") == 0, "Service name should be MaintainTestService"); } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while getting service, raison:" << e.what() << endl; return false; } @@ -43,6 +44,7 @@ bool testMaintainGetService() { bool testMaintainUpdateService() { cout << "in function testMaintainUpdateService" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; NacosServiceFactory *factory = new NacosServiceFactory(configProps); ResourceGuard _guardFactory(factory); @@ -64,7 +66,7 @@ bool testMaintainUpdateService() { ServiceInfo2 serviceInfoQuery = maintainService->queryService("MaintainTestService", NULLSTR); SHOULD_BE_TRUE(serviceInfoQuery.getProtectThreshold() - 2.0 < 1e-9, "protect threshold should be 2.0D"); } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while updating service, raison:" << e.what() << endl; return false; } @@ -76,6 +78,7 @@ bool testMaintainUpdateService() { bool testMaintainCreateService() { cout << "in function testMaintainCreateService" << endl; Properties configProps; + ADD_AUTH_INFO(configProps); configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; NacosServiceFactory *factory = new NacosServiceFactory(configProps); ResourceGuard _guardFactory(factory); @@ -117,7 +120,7 @@ bool testMaintainCreateService() { SHOULD_BE_TRUE(deleteFunctionality, "delete should be successful"); } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while updating service, raison:" << e.what() << endl; return false; } diff --git a/test/testcase/testNamingService.cpp b/test/testcase/testNamingService.cpp index 50a9c09..92da4fd 100644 --- a/test/testcase/testNamingService.cpp +++ b/test/testcase/testNamingService.cpp @@ -22,6 +22,7 @@ bool testNamingProxySmokeTest() { cout << "in function testNamingProxySmokeTest" << endl; NacosString servers = "127.0.0.1:8848"; Properties props; + ADD_AUTH_INFO(props); props[PropertyKeyConst::SERVER_ADDR] = servers; NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); @@ -43,7 +44,7 @@ bool testNamingProxySmokeTest() { namingProxy->deregisterService(serviceName, theinstance); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "Exception caught during deregistering service, raison:" << e.what() << endl; return false; @@ -58,7 +59,7 @@ bool testNamingProxySmokeTest() { sleep(1); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "Exception caught during registering service, raison:" << e.what() << endl; return false; @@ -84,7 +85,7 @@ bool testNamingProxySmokeTest() { namingProxy->deregisterService(serviceName, theinstance); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "Exception caught during cleaning the test environment, raison:" << e.what() << endl; return false; @@ -97,6 +98,7 @@ bool testNamingProxyServerHealthy() { cout << "in function testNamingProxyServerHealthy" << endl; NacosString servers = "127.0.0.1:8848"; Properties props; + ADD_AUTH_INFO(props); props[PropertyKeyConst::SERVER_ADDR] = servers; NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); @@ -110,7 +112,7 @@ bool testNamingProxyServerHealthy() { try { healthy = namingProxy->serverHealthy(); } - catch (NacosException e) { + catch (NacosException &e) { cout << "Exception caught during deregistering service, raison:" << e.what() << endl; return false; @@ -135,6 +137,7 @@ bool testNamingServiceRegister() { cout << "in function testNamingServiceRegister" << endl; Properties configProps; configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; + ADD_AUTH_INFO(configProps); NacosServiceFactory *factory = new NacosServiceFactory(configProps); ResourceGuard _guardFactory(factory); NamingService *namingSvc = factory->CreateNamingService(); @@ -159,7 +162,7 @@ bool testNamingServiceRegister() { } } } - catch (NacosException e) { + catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return false; } diff --git a/test/testcase/testNamingSubscribe.cpp b/test/testcase/testNamingSubscribe.cpp index 9e2cc39..459878f 100644 --- a/test/testcase/testNamingSubscribe.cpp +++ b/test/testcase/testNamingSubscribe.cpp @@ -33,6 +33,7 @@ bool testListenService() { cout << "in function testListenService" << endl; Properties props; props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; + ADD_AUTH_INFO(props); NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); NamingService *n = factory->CreateNamingService(); diff --git a/test/testcase/testPublishConfig.cpp b/test/testcase/testPublishConfig.cpp index 1fbc9ed..8d9e09b 100644 --- a/test/testcase/testPublishConfig.cpp +++ b/test/testcase/testPublishConfig.cpp @@ -15,6 +15,7 @@ bool testPublishConfig() { cout << "in function testPublishConfig" << endl; Properties props; props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; + ADD_AUTH_INFO(props); NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); ConfigService *n = factory->CreateConfigService(); @@ -30,16 +31,20 @@ bool testPublishConfig() { try { bSucc = n->publishConfig(key_s, NULLSTR, val_s); int retry = 0; - ss = n->getConfig(key_s, NULLSTR, 1000); while (!(ss == val_s) && retry++ < 10) { - ss = n->getConfig(key_s, NULLSTR, 1000); + sleep(1); + try { + ss = n->getConfig(key_s, NULLSTR, 1000); + } catch (NacosException & ignore) { + //getConfig may throw 404, but that doesn't matter + } } if (!(ss == val_s)) { throw NacosException(0, "getConfig() failed."); } } - catch (NacosException e) { + catch (NacosException &e) { cout << "Request failed with curl code:" << e.errorcode() << endl << "Reason:" << e.what() << endl; diff --git a/test/testcase/testPublishConfigWithHttpPrefix.cpp b/test/testcase/testPublishConfigWithHttpPrefix.cpp new file mode 100644 index 0000000..dc0be84 --- /dev/null +++ b/test/testcase/testPublishConfigWithHttpPrefix.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include "factory/NacosServiceFactory.h" +#include "ResourceGuard.h" +#include "PropertyKeyConst.h" +#include "DebugAssertion.h" +#include "Debug.h" + +using namespace std; +using namespace nacos; + +bool testPublishConfigWithHttpPrefix() { + cout << "in function testPublishConfigWithHttpPrefix" << endl; + Properties props; + props[PropertyKeyConst::SERVER_ADDR] = "htTp://localhost:8848,HtTP://127.0.0.1:8848"; + ADD_AUTH_INFO(props); + NacosServiceFactory *factory = new NacosServiceFactory(props); + ResourceGuard _guardFactory(factory); + ConfigService *n = factory->CreateConfigService(); + ResourceGuard _serviceFactory(n); + bool bSucc; + for (int i = 0; i < 50; i++) { + char key_s[200]; + char val_s[200]; + sprintf(key_s, "Key%d", i); + sprintf(val_s, "v__%d", i); + NacosString ss = ""; + + try { + bSucc = n->publishConfig(key_s, NULLSTR, val_s); + int retry = 0; + while (!(ss == val_s) && retry++ < 10) { + sleep(1); + try { + ss = n->getConfig(key_s, NULLSTR, 1000); + } catch (NacosException &e) { } + } + n->removeConfig(key_s, NULLSTR); + + if (!(ss == val_s)) { + throw NacosException(0, "getConfig() failed."); + } + } + catch (NacosException &e) { + cout << + "Request failed with curl code:" << e.errorcode() << endl << + "Reason:" << e.what() << endl; + + return false; + } + cout << "Publishing Key:" << key_s << " with value:" << val_s << " result:" << bSucc << endl; + } + + return true; +} \ No newline at end of file