├── src ├── utils │ ├── Env.h │ ├── url.h │ ├── DirUtils.h │ ├── TimeUtils.h │ ├── TimeUtils.cpp │ ├── NetUtils.h │ ├── UuidUtils.h │ ├── ConfigParserUtils.h │ ├── UuidUtils.cpp │ ├── url.cpp │ ├── DirUtils.cpp │ ├── RandomUtils.h │ ├── RandomUtils.cpp │ ├── NamingUtils.h │ ├── ConfigParserUtils.cpp │ ├── NetUtils.cpp │ └── SequenceProvider.h ├── naming │ ├── beat │ │ ├── BeatInfo.cpp │ │ ├── BeatTask.cpp │ │ ├── BeatTask.h │ │ ├── BeatInfo.h │ │ └── BeatReactor.h │ ├── subscribe │ │ ├── EventListener.cpp │ │ ├── HostReactor.h │ │ ├── UdpNamingServiceListener.h │ │ ├── SubscriptionPoller.h │ │ ├── EventDispatcher.h │ │ └── HostReactor.cpp │ ├── selectors │ │ ├── HealthInstanceSelector.cpp │ │ ├── RandomSelector.cpp │ │ └── RandomByWeightSelector.cpp │ ├── Cluster.cpp │ ├── cache │ │ ├── NamingCache.h │ │ ├── NamingCache.cpp │ │ └── ChangeAdvice.cpp │ ├── NacosNamingMaintainService.h │ ├── Instance.cpp │ └── NacosNamingMaintainService.cpp ├── config │ ├── SnapShotSwitch.h │ ├── SnapShotSwitch.cpp │ ├── JVMUtil.h │ ├── ConfigProxy.h │ ├── ConcurrentDiskUtil.h │ ├── IOUtils.h │ ├── AppConfigManager.h │ ├── LocalSnapshotManager.h │ └── ConcurrentDiskUtil.cpp ├── init │ ├── Init.h │ └── Init.cpp ├── NacosExceptions.cpp ├── thread │ ├── Task.h │ ├── Tid.cpp │ ├── Tid.h │ ├── DelayedThreadPool.h │ ├── RWLock.h │ ├── ThreadPool.h │ ├── BlockingQueue.h │ ├── Thread.cpp │ ├── Thread.h │ ├── Mutex.h │ └── ThreadLocal.h ├── crypto │ ├── hmac_sha1 │ │ ├── hmac │ │ │ ├── hmac.h │ │ │ └── hmac_sha1.cpp │ │ ├── README.md │ │ ├── sha │ │ │ └── sha.h │ │ └── LICENSE │ ├── MACProvider.h │ ├── SignatureTool.h │ ├── MACProvider.cpp │ ├── md5 │ │ └── md5.h │ └── base64 │ │ └── base64.h ├── factory │ ├── NacosFactoryFactory.cpp │ ├── NacosServiceFactory.h │ └── ObjectConfigData.h ├── NacosString.cpp ├── constant │ ├── NamingConstant.cpp │ ├── UtilAndComs.cpp │ ├── ConfigConstant.cpp │ └── PropertyKeyConst.cpp ├── listen │ └── OperateItem.h ├── debug │ └── DebugAssertion.h ├── security │ └── SecurityManager.h ├── json │ ├── rapidjson │ │ ├── internal │ │ │ ├── swap.h │ │ │ └── strfunc.h │ │ ├── cursorstreamwrapper.h │ │ ├── ostreamwrapper.h │ │ ├── memorybuffer.h │ │ └── memorystream.h │ └── JSON.h └── http │ └── delegate │ ├── NoOpHttpDelegate.h │ ├── NacosAuthHttpDelegate.h │ ├── NoOpHttpDelegate.cpp │ └── NacosAuthHttpDelegate.cpp ├── include ├── factory │ ├── NacosFactoryFactory.h │ └── INacosServiceFactory.h ├── Compatibility.h ├── naming │ ├── selectors │ │ ├── RandomSelector.h │ │ ├── HealthInstanceSelector.h │ │ ├── RandomByWeightSelector.h │ │ └── Selector.h │ ├── ListView.h │ ├── ChangeAdvice.h │ ├── Cluster.h │ ├── subscribe │ │ └── EventListener.h │ ├── NamingMaintainService.h │ ├── Instance.h │ └── ServiceInfo.h ├── ResourceGuard.h ├── server │ └── ServerSelector.h ├── thread │ └── AtomicInt.h ├── Properties.h ├── constant │ ├── UtilAndComs.h │ ├── NamingConstant.h │ ├── ConfigConstant.h │ └── PropertyKeyConst.h ├── listen │ └── Listener.h ├── Nacos.h ├── NacosString.h └── config │ └── ConfigService.h ├── test └── testcase │ ├── testNetUtils.cpp │ ├── testAppConfigManager.cpp │ ├── AssertString.cpp │ ├── testURL.cpp │ ├── DebugTest.cpp │ ├── testMD5.cpp │ ├── testRapidJson.cpp │ ├── testUUID.cpp │ ├── testDeleteConfig.cpp │ ├── testGetServiceNames.cpp │ ├── testSequenceProvider.cpp │ ├── testServerListManager.cpp │ ├── testPublishConfigWithHttpPrefix.cpp │ ├── testPublishConfig.cpp │ ├── testDeleteListenedKeys.cpp │ ├── testListenWorker.cpp │ ├── testListeningKeysWithHttpPrefix.cpp │ ├── testGetConfig.cpp │ ├── testHttpRequest.cpp │ ├── testDelayedThreadPool.cpp │ └── testEndpointWithNamingSvc.cpp ├── examples ├── generate_examples.sh ├── getConfig.cpp ├── getAllInstances.cpp ├── IntegratingIntoYourProject.cpp ├── setConfig.cpp ├── listenToKeys.cpp ├── registerInstances.cpp └── subscribeServices.cpp ├── .gitignore ├── nacos-cpp-cli.properties └── CMakeLists.txt /src/utils/Env.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const char* getEnv(const char* env) { 4 | if (env == NULL) { 5 | return NULL; 6 | } 7 | char* var = getenv(env); 8 | return var; 9 | } -------------------------------------------------------------------------------- /src/naming/beat/BeatInfo.cpp: -------------------------------------------------------------------------------- 1 | #include "src/json/JSON.h" 2 | #include "BeatInfo.h" 3 | #include "NacosString.h" 4 | 5 | namespace nacos{ 6 | NacosString BeatInfo::toString() { 7 | return JSON::toJSONString(*this); 8 | } 9 | }//namespace nacos -------------------------------------------------------------------------------- /src/utils/url.h: -------------------------------------------------------------------------------- 1 | #ifndef __URL_H_ 2 | #define __URL_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | namespace nacos{ 7 | NacosString urlencode(const NacosString &content); 8 | 9 | NacosString urldecode(const NacosString &content); 10 | }//namespace nacos 11 | 12 | #endif -------------------------------------------------------------------------------- /src/naming/subscribe/EventListener.cpp: -------------------------------------------------------------------------------- 1 | #include "naming/subscribe/EventListener.h" 2 | #include "src/debug/DebugAssertion.h" 3 | 4 | namespace nacos { 5 | 6 | EventListener::~EventListener() { 7 | NACOS_ASSERT(refCnt() == 0) 8 | } 9 | 10 | }//namespace nacos 11 | -------------------------------------------------------------------------------- /src/utils/DirUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef __DIR_UTILS_H_ 2 | #define __DIR_UTILS_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | namespace nacos{ 7 | class DirUtils { 8 | public: 9 | static NacosString getHome(); 10 | 11 | static NacosString getCwd(); 12 | }; 13 | }//namespace nacos 14 | 15 | #endif -------------------------------------------------------------------------------- /src/utils/TimeUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIME_UTILS_H_ 2 | #define __TIME_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | namespace nacos{ 8 | class TimeUtils { 9 | public: 10 | static int64_t getCurrentTimeInMs(); 11 | static void getCurrentTimeInStruct(struct timeval &tv); 12 | 13 | }; 14 | }//namespace nacos 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/config/SnapShotSwitch.h: -------------------------------------------------------------------------------- 1 | #ifndef __SS_SWITCH_H_ 2 | #define __SS_SWITCH_H_ 3 | 4 | namespace nacos{ 5 | class SnapShotSwitch { 6 | private: 7 | /** 8 | * whether use local cache 9 | */ 10 | static bool isSnapShot; 11 | public: 12 | static bool getIsSnapShot(); 13 | 14 | static void setIsSnapShot(bool isSnapShot); 15 | }; 16 | }//namespace nacos 17 | 18 | #endif -------------------------------------------------------------------------------- /include/factory/NacosFactoryFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef NACOS_FACTORY_FACTORY_H 2 | #define NACOS_FACTORY_FACTORY_H 3 | #include "factory/INacosServiceFactory.h" 4 | namespace nacos { 5 | class NacosFactoryFactory { 6 | public: 7 | static INacosServiceFactory *getNacosFactory(const NacosString &_configFile); 8 | static INacosServiceFactory *getNacosFactory(Properties &_props); 9 | }; 10 | } 11 | #endif -------------------------------------------------------------------------------- /src/config/SnapShotSwitch.cpp: -------------------------------------------------------------------------------- 1 | #include "LocalSnapshotManager.h" 2 | #include "SnapShotSwitch.h" 3 | 4 | namespace nacos{ 5 | bool SnapShotSwitch::getIsSnapShot() { 6 | return isSnapShot; 7 | }; 8 | 9 | void SnapShotSwitch::setIsSnapShot(bool isSnapShot) { 10 | SnapShotSwitch::isSnapShot = isSnapShot; 11 | //LocalConfigInfoProcessor::cleanAllSnapshot(); 12 | }; 13 | }//namespace nacos -------------------------------------------------------------------------------- /src/init/Init.h: -------------------------------------------------------------------------------- 1 | #ifndef __INIT_H_ 2 | #define __INIT_H_ 3 | 4 | #include "src/thread/Mutex.h" 5 | 6 | namespace nacos{ 7 | class Init { 8 | private: 9 | static bool inited; 10 | static Mutex initflagMutex; 11 | public: 12 | Init() {}; 13 | 14 | ~Init() { doDeinit(); }; 15 | 16 | static void doInit(); 17 | 18 | static void doDeinit(); 19 | }; 20 | }//namespace nacos 21 | 22 | #endif -------------------------------------------------------------------------------- /src/utils/TimeUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/utils/TimeUtils.h" 3 | 4 | namespace nacos{ 5 | int64_t TimeUtils::getCurrentTimeInMs() { 6 | struct timeval tv; 7 | gettimeofday(&tv, NULL); 8 | 9 | return tv.tv_sec * 1000 + tv.tv_usec / 1000; 10 | } 11 | 12 | void TimeUtils::getCurrentTimeInStruct(struct timeval &tv) { 13 | gettimeofday(&tv, NULL); 14 | } 15 | 16 | }//namespace nacos 17 | -------------------------------------------------------------------------------- /src/NacosExceptions.cpp: -------------------------------------------------------------------------------- 1 | #include "NacosExceptions.h" 2 | 3 | namespace nacos{ 4 | NacosException::NacosException(int errorcode, const char *errormsg) NACOS_NOTHROW() { 5 | _errcode = errorcode; 6 | _errmsg = errormsg; 7 | } 8 | 9 | NacosException::NacosException(int errorcode, const NacosString &errormsg) NACOS_NOTHROW() { 10 | _errcode = errorcode; 11 | _errmsg = errormsg; 12 | } 13 | }//namespace nacos 14 | -------------------------------------------------------------------------------- /include/Compatibility.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/4/7. 3 | // Compatibility header 4 | 5 | #ifndef NACOS_SDK_CPP_COMPATIBILITY_H 6 | #define NACOS_SDK_CPP_COMPATIBILITY_H 7 | 8 | #if __cplusplus >= 201402L 9 | //C++ 17 compatibility 10 | #define NACOS_THROW(...) 11 | #define NACOS_NOTHROW() noexcept 12 | #else 13 | #define NACOS_THROW throw 14 | #define NACOS_NOTHROW throw 15 | #endif 16 | 17 | #endif //NACOS_SDK_CPP_COMPATIBILITY_H 18 | -------------------------------------------------------------------------------- /include/naming/selectors/RandomSelector.h: -------------------------------------------------------------------------------- 1 | #ifndef __RND_SELECTOR_H_ 2 | #define __RND_SELECTOR_H_ 3 | 4 | #include 5 | #include "naming/selectors/Selector.h" 6 | 7 | namespace nacos { namespace naming { namespace selectors { 8 | class RandomSelector : public Selector{ 9 | private: 10 | public: 11 | std::list select(const std::list &instancesToSelect); 12 | }; 13 | } /*selectors*/ } /*naming*/ }/*nacos*/ 14 | 15 | #endif -------------------------------------------------------------------------------- /src/thread/Task.h: -------------------------------------------------------------------------------- 1 | #ifndef __TASK_H_ 2 | #define __TASK_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | namespace nacos{ 7 | class Task { 8 | private: 9 | NacosString _taskName; 10 | public: 11 | virtual void run() = 0; 12 | 13 | virtual ~Task() {}; 14 | 15 | void setTaskName(const NacosString &taskName) { _taskName = taskName; }; 16 | 17 | const NacosString &getTaskName() const { return _taskName; }; 18 | }; 19 | 20 | }//namespace nacos 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/utils/NetUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef __NET_UTILS_H_ 2 | #define __NET_UTILS_H_ 3 | 4 | #include "NacosString.h" 5 | #include "NacosExceptions.h" 6 | #include "Compatibility.h" 7 | 8 | namespace nacos{ 9 | class NetUtils { 10 | public: 11 | //Get IP address (best guess) 12 | static NacosString getHostIp() NACOS_THROW(NacosException); 13 | 14 | //Get hostname 15 | static NacosString getHostName() NACOS_THROW(NacosException); 16 | }; 17 | }//namespace nacos 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/naming/selectors/HealthInstanceSelector.h: -------------------------------------------------------------------------------- 1 | #ifndef __HEALTH_INST_SELECTOR_H_ 2 | #define __HEALTH_INST_SELECTOR_H_ 3 | 4 | #include 5 | #include "naming/selectors/Selector.h" 6 | 7 | namespace nacos { namespace naming { namespace selectors { 8 | 9 | class HealthInstanceSelector : public Selector{ 10 | private: 11 | public: 12 | std::list select(const std::list &instancesToSelect); 13 | }; 14 | } /*selectors*/ } /*naming*/ }/*nacos*/ 15 | 16 | #endif -------------------------------------------------------------------------------- /src/utils/UuidUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UUID_UTILS_H_ 2 | #define __UUID_UTILS_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | #define UUID_LEN_BYTES 16 7 | 8 | /** 9 | * UuidUtils 10 | * 11 | * @author yzz-ihep 12 | * Generates UUID from /dev/urandom 13 | */ 14 | 15 | namespace nacos{ 16 | class UuidUtils { 17 | private: 18 | public: 19 | static NacosString generateUuid(); 20 | 21 | static void Init(); 22 | 23 | static void DeInit(); 24 | }; 25 | }//namespace nacos 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /test/testcase/testNetUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/utils//NetUtils.h" 3 | #include "src/debug/DebugAssertion.h" 4 | 5 | using namespace std; 6 | using namespace nacos; 7 | 8 | bool testGetHostIp() { 9 | cout << "in function testGetHostIp" << endl; 10 | 11 | NacosString ip = NetUtils::getHostIp(); 12 | cout << "ip:" << ip << endl; 13 | SHOULD_BE_TRUE(!ip.empty(), "Ip got for local machine should not be empty"); 14 | cout << "test end..." << endl; 15 | 16 | return true; 17 | } -------------------------------------------------------------------------------- /src/utils/ConfigParserUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/1/9. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_CONFIGPARSERUTILS_H 6 | #define NACOS_SDK_CPP_CONFIGPARSERUTILS_H 7 | #include "Properties.h" 8 | #include "NacosExceptions.h" 9 | #include "Compatibility.h" 10 | 11 | namespace nacos { 12 | 13 | class ConfigParserUtils { 14 | public: 15 | static Properties parseConfigFile(const NacosString &file) NACOS_THROW(NacosException); 16 | 17 | }; 18 | 19 | } 20 | 21 | #endif //NACOS_SDK_CPP_CONFIGPARSERUTILS_H 22 | -------------------------------------------------------------------------------- /include/naming/selectors/RandomByWeightSelector.h: -------------------------------------------------------------------------------- 1 | #ifndef __WEIGHTED_RND_SELECTOR_H_ 2 | #define __WEIGHTED_RND_SELECTOR_H_ 3 | 4 | #include 5 | #include "naming/selectors/Selector.h" 6 | 7 | #define BASIC_WEIGHT 65536 8 | 9 | namespace nacos { namespace naming { namespace selectors { 10 | class RandomByWeightSelector : public Selector{ 11 | private: 12 | public: 13 | std::list select(const std::list &instancesToSelect); 14 | }; 15 | } /*selectors*/ } /*naming*/ }/*nacos*/ 16 | 17 | #endif -------------------------------------------------------------------------------- /include/naming/selectors/Selector.h: -------------------------------------------------------------------------------- 1 | #ifndef __SELECTOR_H_ 2 | #define __SELECTOR_H_ 3 | 4 | #include 5 | #include "naming/Instance.h" 6 | 7 | namespace nacos { namespace naming { namespace selectors { 8 | //Selector interface definition 9 | //All Selectors shall be THREAD-SAFE! 10 | 11 | template 12 | class Selector { 13 | private: 14 | public: 15 | virtual std::list select(const std::list &itemsToSelect) = 0; 16 | 17 | virtual ~Selector() {}; 18 | }; 19 | 20 | } /*selectors*/ } /*naming*/ }/*nacos*/ 21 | 22 | #endif -------------------------------------------------------------------------------- /src/crypto/hmac_sha1/hmac/hmac.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_hmac.h Interface to HMAC functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #ifndef HMAC_H_ 8 | #define HMAC_H_ (1) 9 | 10 | #include 11 | 12 | void hmac_sha1(const uint8_t *k, /* secret key */ 13 | size_t lk, /* length of the key in bytes */ 14 | const uint8_t *d, /* data */ 15 | size_t ld, /* length of data in bytes */ 16 | uint8_t *out, /* output buffer, at least "t" bytes */ 17 | size_t *t); 18 | 19 | #endif // HMAC_H_ 20 | -------------------------------------------------------------------------------- /src/thread/Tid.cpp: -------------------------------------------------------------------------------- 1 | #include "src/thread/Tid.h" 2 | 3 | #if defined(__CYGWIN__) || defined(MS_WINDOWS) 4 | //TODO:for windows/cygwin 5 | 6 | #elif defined(linux) 7 | //for linux 8 | //solved in header file 9 | 10 | #elif defined(__APPLE__) && defined(__MACH__) 11 | //Mac OS code goes here 12 | #include 13 | TID_T gettidv1() { 14 | TID_T tid; 15 | pthread_threadid_np(NULL, &tid); 16 | 17 | return tid; 18 | } 19 | #else 20 | //regard the system as an unix-like system 21 | //for linux solved in header file 22 | 23 | #endif//OS-specific code 24 | -------------------------------------------------------------------------------- /src/factory/NacosFactoryFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "factory/NacosFactoryFactory.h" 2 | #include "src/factory/NacosServiceFactory.h" 3 | namespace nacos { 4 | 5 | INacosServiceFactory *NacosFactoryFactory::getNacosFactory(const NacosString &_configFile) { 6 | NacosServiceFactory *factory = new NacosServiceFactory(_configFile); 7 | return factory; 8 | } 9 | 10 | INacosServiceFactory *NacosFactoryFactory::getNacosFactory(Properties &_props) { 11 | NacosServiceFactory *factory = new NacosServiceFactory(_props); 12 | return factory; 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /include/naming/ListView.h: -------------------------------------------------------------------------------- 1 | #ifndef __NACOS_LIST_VUE_H_ 2 | #define __NACOS_LIST_VUE_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | 7 | namespace nacos{ 8 | template 9 | class ListView{ 10 | private: 11 | int count; 12 | std::list data; 13 | public: 14 | ListView() { count = 0; }; 15 | int getCount() const { return count; }; 16 | std::list getData() const { return data; }; 17 | void setCount(int _count) { count = _count; }; 18 | void setData(const std::list &_data) { data = _data; }; 19 | }; 20 | }//namespace nacos 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/crypto/hmac_sha1/README.md: -------------------------------------------------------------------------------- 1 | hmac-sha1 2 | ========= 3 | 4 | [![Build Status](https://travis-ci.org/Akagi201/hmac-sha1.svg)](https://travis-ci.org/Akagi201/hmac-sha1) 5 | 6 | Standalone implementation of `HMAC()` + `EVP_sha1()` in `OpenSSL` 7 | 8 | ## API 9 | 10 | ``` 11 | #include "hmac/hmac.h" 12 | 13 | void hmac_sha1(const uint8_t *k, /* secret key */ 14 | size_t lk, /* length of the key in bytes */ 15 | const uint8_t *d, /* data */ 16 | size_t ld, /* length of data in bytes */ 17 | uint8_t *out, /* output buffer, at least "t" bytes */ 18 | size_t *t); 19 | ``` -------------------------------------------------------------------------------- /include/ResourceGuard.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/9/6. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_RESOURCEGUARD_H 6 | #define NACOS_SDK_CPP_RESOURCEGUARD_H 7 | 8 | namespace nacos{ 9 | template 10 | class ResourceGuard { 11 | private: 12 | T *_obj;//The object being watched 13 | ResourceGuard(); 14 | 15 | public: 16 | ResourceGuard(T *obj) { _obj = obj; }; 17 | 18 | ~ResourceGuard() { 19 | if (_obj != NULL) { 20 | delete _obj; 21 | _obj = NULL; 22 | } 23 | }; 24 | }; 25 | }//namespace nacos 26 | 27 | 28 | #endif //NACOS_SDK_CPP_RESOURCEGUARD_H 29 | -------------------------------------------------------------------------------- /test/testcase/testAppConfigManager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/config/AppConfigManager.h" 3 | #include "src/utils/DirUtils.h" 4 | #include "constant/ConfigConstant.h" 5 | 6 | using namespace std; 7 | using namespace nacos; 8 | 9 | bool testAppConfigManager() { 10 | cout << "in function testAppConfigManager" << endl; 11 | 12 | NacosString configFile = DirUtils::getCwd() + ConfigConstant::FILE_SEPARATOR + ConfigConstant::DEFAULT_CONFIG_FILE; 13 | AppConfigManager appConfigManager(configFile); 14 | appConfigManager.loadConfig(configFile); 15 | Properties configs = appConfigManager.getAllConfig(); 16 | return true; 17 | } -------------------------------------------------------------------------------- /src/naming/selectors/HealthInstanceSelector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "naming/selectors/HealthInstanceSelector.h" 3 | 4 | namespace nacos { namespace naming { namespace selectors { 5 | 6 | std::list HealthInstanceSelector::select(const std::list &instancesToSelect){ 7 | std::list result; 8 | for (std::list::const_iterator it = instancesToSelect.begin(); 9 | it != instancesToSelect.end(); it++) { 10 | if (it->healthy) { 11 | result.push_back(*it); 12 | } 13 | } 14 | 15 | return result; 16 | } 17 | 18 | } /*selectors*/ } /*naming*/ }/*nacos*/ 19 | -------------------------------------------------------------------------------- /examples/generate_examples.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | g++ -I/usr/local/include/nacos/ IntegratingIntoYourProject.cpp -lnacos-cli -o IntegratingIntoYourProject.out 4 | g++ -I/usr/local/include/nacos/ getAllInstances.cpp -lnacos-cli -o getAllInstances.out 5 | g++ -I/usr/local/include/nacos/ getConfig.cpp -lnacos-cli -o getConfig.out 6 | g++ -I/usr/local/include/nacos/ listenToKeys.cpp -lnacos-cli -o listenToKeys.out 7 | g++ -I/usr/local/include/nacos/ registerInstances.cpp -lnacos-cli -o registerInstances.out 8 | g++ -I/usr/local/include/nacos/ setConfig.cpp -lnacos-cli -o setConfig.out 9 | g++ -I/usr/local/include/nacos/ subscribeServices.cpp -lnacos-cli -o subscribeServices.out 10 | -------------------------------------------------------------------------------- /src/NacosString.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "NacosString.h" 5 | 6 | namespace nacos{ 7 | const NacosString NacosStringOps::nullstr = ""; 8 | const NacosString NacosStringOps::STR_TRUE = "true"; 9 | const NacosString NacosStringOps::STR_FALSE = "false"; 10 | 11 | //Returns true if str refers to nullstr 12 | bool NacosStringOps::isNullStr(const NacosString &str) { 13 | return (&str == &nullstr) || (str == ""); 14 | } 15 | 16 | template<> 17 | NacosString NacosStringOps::valueOf(bool val) { 18 | if (val) { return STR_TRUE; } 19 | else { return STR_FALSE; } 20 | } 21 | }//namespace nacos 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # temp 35 | tmp/ 36 | 37 | # CMakeFiles 38 | CMakeFiles/ 39 | CMakeLists.txt 40 | CMakeCache.txt 41 | cmake_install.cmake 42 | install_manifest.txt 43 | Makefile 44 | 45 | # idea project 46 | .idea 47 | cmake-build-debug 48 | 49 | *.dat 50 | 51 | 52 | .vscode/ -------------------------------------------------------------------------------- /include/server/ServerSelector.h: -------------------------------------------------------------------------------- 1 | #ifndef NACOS_SDK_CPP_SERVERSELECTOR_H 2 | #define NACOS_SDK_CPP_SERVERSELECTOR_H 3 | 4 | #include "NacosServerInfo.h" 5 | #include 6 | 7 | /* 8 | * ServerSelector 9 | * Author: Liu, Hanyu 10 | * Selector interface, to select one server from the select list 11 | * User can implement different selecting strategies (e.g.: Weighed, Random, Least used) by implementing select() method 12 | */ 13 | namespace nacos{ 14 | class ServerSelector { 15 | public: 16 | virtual NacosServerInfo select(std::list &serverList) = 0; 17 | 18 | virtual ~ServerSelector() {}; 19 | }; 20 | }//namespace nacos 21 | 22 | #endif //NACOS_SDK_CPP_SERVERSELECTOR_H 23 | -------------------------------------------------------------------------------- /src/config/JVMUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef __JVMUTIL_H_ 2 | #define __JVMUTIL_H_ 3 | 4 | namespace nacos{ 5 | class JVMUtil { 6 | public: 7 | /** 8 | * whether is multi instance 9 | * 10 | * @return whether multi 11 | */ 12 | static bool isMultiInstance() { 13 | return _isMultiInstance; 14 | }; 15 | private: 16 | static bool _isMultiInstance; 17 | 18 | /*static { 19 | NacosString multiDeploy = System.getProperty("isMultiInstance", "false"); 20 | if (TRUE.equals(multiDeploy)) { 21 | isMultiInstance = true; 22 | } 23 | LOGGER.info("isMultiInstance:{}", isMultiInstance); 24 | }*/ 25 | }; 26 | }//namespace nacos 27 | 28 | #endif -------------------------------------------------------------------------------- /test/testcase/AssertString.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "NacosString.h" 3 | #include "src/debug/DebugAssertion.h" 4 | 5 | using namespace std; 6 | using namespace nacos; 7 | 8 | //Use a special variable NULLSTR as null in Java to pass null parameter 9 | //But "" (zero-length string) will still be regarded as null 10 | bool testStringEqual() { 11 | cout << "In testStringEqual" << endl; 12 | NacosString s2 = ""; 13 | NacosString s3 = "Nacos"; 14 | SHOULD_BE_TRUE(isNull(NULLSTR), "NULLSTR should be NULL"); 15 | SHOULD_BE_TRUE(isNull(s2), "\"\" should be NULL"); 16 | SHOULD_BE_FALSE(isNull(s3), "\"Nacos\" should not be NULL"); 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /test/testcase/testURL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "src/utils/url.h" 4 | #include "src/debug/DebugAssertion.h" 5 | #include "src/log/Logger.h" 6 | 7 | using namespace std; 8 | using namespace nacos; 9 | 10 | bool testURLEncodeAndDecode() { 11 | cout << "in function testURLEncode" << endl; 12 | 13 | NacosString originalContent = "Hello W! orld \\/,.%$@^%#*43543"; 14 | NacosString encoded = urlencode(originalContent); 15 | cout << "Encoded:" << encoded << endl; 16 | NacosString decoded = urldecode(encoded); 17 | SHOULD_BE_TRUE(originalContent == decoded, "After encoding and decoding, the content should remain the same."); 18 | 19 | return true; 20 | } 21 | -------------------------------------------------------------------------------- /src/naming/Cluster.cpp: -------------------------------------------------------------------------------- 1 | #include "naming/Cluster.h" 2 | 3 | namespace nacos{ 4 | 5 | NacosString Cluster::getName() const { 6 | return name; 7 | } 8 | 9 | void Cluster::setName(const NacosString &name) { 10 | Cluster::name = name; 11 | } 12 | 13 | HealthChecker Cluster::getHealthChecker() const { 14 | return healthChecker; 15 | } 16 | 17 | void Cluster::setHealthChecker(const HealthChecker &healthChecker) { 18 | Cluster::healthChecker = healthChecker; 19 | } 20 | 21 | std::map Cluster::getMetadata() const { 22 | return metadata; 23 | } 24 | 25 | void Cluster::setMetadata(const std::map &metadata) { 26 | Cluster::metadata = metadata; 27 | } 28 | 29 | }//namespace nacos 30 | -------------------------------------------------------------------------------- /include/thread/AtomicInt.h: -------------------------------------------------------------------------------- 1 | #ifndef __ATOMIC_INT_H_ 2 | #define __ATOMIC_INT_H_ 3 | 4 | namespace nacos{ 5 | template 6 | class AtomicInt { 7 | private: 8 | volatile T _curval; 9 | public: 10 | AtomicInt(T curval = 0) : _curval(curval) {}; 11 | 12 | void set(T val) { _curval = val; }; 13 | 14 | T inc(T incval = 1) { 15 | T oldValue = getAndInc(incval); 16 | return incval + oldValue; 17 | }; 18 | 19 | T getAndInc(T incval = 1) { 20 | T oldValue = __sync_fetch_and_add(&_curval, incval); 21 | return oldValue; 22 | } 23 | 24 | T dec(int decval = 1) { 25 | return inc(-decval); 26 | }; 27 | 28 | T get() const { return _curval; }; 29 | }; 30 | }//namespace nacos 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/Properties.h: -------------------------------------------------------------------------------- 1 | #ifndef __PROPERTIES_H_ 2 | #define __PROPERTIES_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | 7 | namespace nacos{ 8 | class Properties : public std::map { 9 | public: 10 | NacosString toString() const { 11 | NacosString content = ""; 12 | for (std::map::const_iterator it = begin(); it != end(); it++) { 13 | content += (it->first + "=" + it->second + "\n"); 14 | } 15 | return content; 16 | } 17 | 18 | bool contains(const NacosString &key) const { 19 | if (count(key) > 0) { 20 | return true; 21 | } 22 | 23 | return false; 24 | } 25 | }; 26 | }//namespace nacos 27 | 28 | #endif -------------------------------------------------------------------------------- /include/constant/UtilAndComs.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTIL_N_COMS_H_ 2 | #define __UTIL_N_COMS_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | namespace nacos{ 7 | class UtilAndComs { 8 | public: 9 | static NacosString VERSION; 10 | 11 | static NacosString ENCODING; 12 | 13 | static NacosString NACOS_URL_BASE; 14 | 15 | static NacosString NACOS_URL_INSTANCE; 16 | 17 | static int REQUEST_DOMAIN_RETRY_COUNT; 18 | 19 | static NacosString SERVER_ADDR_IP_SPLITER; 20 | 21 | static int DEFAULT_CLIENT_BEAT_THREAD_COUNT;//TODO:Calc this according to nr_processors of the host 22 | 23 | static int DEFAULT_POLLING_THREAD_COUNT;//TODO:Calc this according to nr_processors of the host 24 | 25 | static void Init(); 26 | }; 27 | }//namespace nacos 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/naming/subscribe/HostReactor.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/1/7. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_HOSTREACTOR_H 6 | #define NACOS_SDK_CPP_HOSTREACTOR_H 7 | #include 8 | #include "NacosString.h" 9 | #include "naming/ServiceInfo.h" 10 | #include "src/factory/ObjectConfigData.h" 11 | #include "src/thread/RWLock.h" 12 | 13 | namespace nacos { 14 | 15 | class HostReactor { 16 | private: 17 | ObjectConfigData *_objectConfigData; 18 | //memory cache 19 | std::map serviceInfoMap; 20 | //rw lock for serviceInfoMap 21 | RWLock rwLock; 22 | public: 23 | HostReactor(ObjectConfigData *objectConfigData); 24 | void processServiceJson(const NacosString &json); 25 | }; 26 | 27 | } 28 | 29 | #endif //NACOS_SDK_CPP_HOSTREACTOR_H 30 | -------------------------------------------------------------------------------- /src/utils/UuidUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "src/utils/UuidUtils.h" 7 | #include "src/utils/RandomUtils.h" 8 | 9 | namespace nacos{ 10 | void UuidUtils::Init() { 11 | } 12 | 13 | void UuidUtils::DeInit() { 14 | } 15 | 16 | NacosString UuidUtils::generateUuid() { 17 | char random_num[UUID_LEN_BYTES]; 18 | char str_buffer[33]; 19 | 20 | //an UUID has 128 bits(16 bytes), so we need to get 16 bytes from the urandom 21 | RandomUtils::getRandomBuffer(random_num, UUID_LEN_BYTES); 22 | 23 | int32_t *val_ptr = (int32_t *) random_num; 24 | snprintf(str_buffer, sizeof(str_buffer), "%08X%08X%08X%08X", val_ptr[0], val_ptr[1], val_ptr[2], val_ptr[3]); 25 | 26 | NacosString uuid = str_buffer; 27 | return uuid; 28 | } 29 | 30 | }//namespace nacos 31 | -------------------------------------------------------------------------------- /src/config/ConfigProxy.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/7/6. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_CONFIGPROXY_H 6 | #define NACOS_SDK_CPP_CONFIGPROXY_H 7 | #include "src/factory/ObjectConfigData.h" 8 | #include "src/http/IHttpCli.h" 9 | 10 | namespace nacos { 11 | 12 | class ConfigProxy { 13 | private: 14 | ObjectConfigData *_objectConfigData; 15 | NacosString getDataToSign(const std::list ¶mValues, const NacosString &nowTimeMs); 16 | public: 17 | ConfigProxy(ObjectConfigData *objectConfigData) : _objectConfigData(objectConfigData) {}; 18 | HttpResult reqAPI(int method, const NacosString &path, std::list &headers, std::list ¶mValues, 19 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 20 | 21 | }; 22 | 23 | } 24 | 25 | #endif //NACOS_SDK_CPP_CONFIGPROXY_H 26 | -------------------------------------------------------------------------------- /include/listen/Listener.h: -------------------------------------------------------------------------------- 1 | #ifndef __LISTENER_H_ 2 | #define __LISTENER_H_ 3 | 4 | #include "NacosString.h" 5 | #include "thread/AtomicInt.h" 6 | 7 | namespace nacos{ 8 | class Listener { 9 | private: 10 | NacosString listenerName; 11 | AtomicInt refCount; 12 | public: 13 | Listener() { 14 | this->listenerName = "theListener"; 15 | }; 16 | 17 | int incRef() { return refCount.inc(); }; 18 | 19 | int decRef() { return refCount.dec(); }; 20 | 21 | int refCnt() const { return refCount.get(); }; 22 | 23 | void setListenerName(const NacosString &name) { this->listenerName = name; }; 24 | 25 | NacosString getListenerName() const { return listenerName; }; 26 | 27 | virtual void receiveConfigInfo(const NacosString &configInfo) = 0; 28 | 29 | virtual ~Listener() {}; 30 | }; 31 | }//namespace nacos 32 | 33 | #endif -------------------------------------------------------------------------------- /include/factory/INacosServiceFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/8/30. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_INACOSSERVICEFACTORY_H 6 | #define NACOS_SDK_CPP_INACOSSERVICEFACTORY_H 7 | 8 | #include "naming/NamingService.h" 9 | #include "naming/NamingMaintainService.h" 10 | #include "config/ConfigService.h" 11 | #include "Properties.h" 12 | 13 | namespace nacos{ 14 | class INacosServiceFactory { 15 | public: 16 | virtual void setConfig(const NacosString &_configFile) = 0; 17 | 18 | virtual void setProps(Properties &_props) = 0; 19 | 20 | virtual NamingService *CreateNamingService() = 0; 21 | 22 | virtual ConfigService *CreateConfigService() = 0; 23 | 24 | virtual NamingMaintainService *CreateNamingMaintainService() = 0; 25 | 26 | virtual ~INacosServiceFactory() {}; 27 | }; 28 | 29 | }//namespace nacos 30 | 31 | #endif //NACOS_SDK_CPP_INACOSSERVICEFACTORY_H 32 | -------------------------------------------------------------------------------- /src/thread/Tid.h: -------------------------------------------------------------------------------- 1 | #ifndef __TID_HELPER_H_ 2 | #define __TID_HELPER_H_ 3 | #if defined(__CYGWIN__) || defined(MS_WINDOWS) 4 | //TODO:for windows/cygwin 5 | #include 6 | #include 7 | #define TID_T pid_t 8 | #define gettidv1() syscall(__NR_gettid) 9 | 10 | #elif defined(linux) || defined(LINUX) 11 | //for linux 12 | #include 13 | #include 14 | #define TID_T pid_t 15 | #define gettidv1() syscall(__NR_gettid) 16 | //#define gettidv2() syscall(SYS_gettid) 17 | 18 | #elif defined(__APPLE__) && defined(__MACH__) 19 | //Mac OS code goes here 20 | #define TID_T unsigned long long 21 | TID_T gettidv1(); 22 | 23 | #else 24 | //regard the system as an unix-like system 25 | #include 26 | #include 27 | #define TID_T pid_t 28 | #define gettidv1() syscall(__NR_gettid) 29 | 30 | #endif//OS-specific code 31 | 32 | #endif//HEADER_GUARD 33 | -------------------------------------------------------------------------------- /examples/getConfig.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Nacos.h" 3 | 4 | using namespace std; 5 | using namespace nacos; 6 | 7 | int main() { 8 | Properties props; 9 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848";//Server address 10 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 11 | ResourceGuard _guardFactory(factory); 12 | ConfigService *n = factory->CreateConfigService(); 13 | ResourceGuard _serviceFactory(n); 14 | NacosString ss = ""; 15 | try { 16 | ss = n->getConfig("k", NULLSTR, 1000); 17 | } 18 | catch (NacosException &e) { 19 | cout << 20 | "Request failed with curl code:" << e.errorcode() << endl << 21 | "Reason:" << e.what() << endl; 22 | return -1; 23 | } 24 | cout << ss << endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /examples/getAllInstances.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Nacos.h" 4 | 5 | using namespace std; 6 | using namespace nacos; 7 | 8 | int main() { 9 | Properties configProps; 10 | configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; 11 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(configProps); 12 | ResourceGuard _guardFactory(factory); 13 | NamingService *namingSvc = factory->CreateNamingService(); 14 | ResourceGuard _guardService(namingSvc); 15 | 16 | list instances = namingSvc->getAllInstances("TestNamingService1"); 17 | cout << "getAllInstances from server:" << endl; 18 | for (list::iterator it = instances.begin(); 19 | it != instances.end(); it++) { 20 | cout << "Instance:" << it->toString() << endl; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /include/Nacos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2020 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef _NACOS_H_ 17 | 18 | #define _NACOS_H_ 19 | #include "factory/INacosServiceFactory.h" 20 | #include "factory/NacosFactoryFactory.h" 21 | #include "constant/PropertyKeyConst.h" 22 | #include "ResourceGuard.h" 23 | 24 | #endif -------------------------------------------------------------------------------- /include/naming/ChangeAdvice.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHG_ADVICE_H_ 2 | #define __CHG_ADVICE_H_ 3 | 4 | #include "NacosString.h" 5 | #include "naming/ServiceInfo.h" 6 | 7 | //The wrapper class for service change information 8 | namespace nacos{ 9 | class ChangeAdvice { 10 | public: 11 | bool added;//indicates Instance is added 12 | bool removed;//indicates Instance is removed 13 | bool modified;//indicates Instance is modified 14 | //std::list addedInstances; 15 | //std::list removedInstances; 16 | //std::list modifiedInstances; 17 | //ServiceInfo oldServiceInfo; 18 | ServiceInfo newServiceInfo; 19 | NacosString key; 20 | public: 21 | ChangeAdvice(); 22 | ~ChangeAdvice(); 23 | static void compareChange(ServiceInfo &oldInfo, ServiceInfo &newInfo, ChangeAdvice &changeAdvice); 24 | NacosString toString(); 25 | }; 26 | }//namespace nacos 27 | 28 | #endif -------------------------------------------------------------------------------- /examples/IntegratingIntoYourProject.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Nacos.h" 3 | 4 | using namespace std; 5 | using namespace nacos; 6 | 7 | int main() { 8 | Properties props; 9 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848";//Server address 10 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 11 | ResourceGuard _guardFactory(factory); 12 | ConfigService *n = factory->CreateConfigService(); 13 | ResourceGuard _serviceFactory(n); 14 | NacosString ss = ""; 15 | try { 16 | ss = n->getConfig("k", NULLSTR, 1000); 17 | } 18 | catch (NacosException &e) { 19 | cout << 20 | "Request failed with curl code:" << e.errorcode() << endl << 21 | "Reason:" << e.what() << endl; 22 | return -1; 23 | } 24 | cout << ss << endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /include/naming/Cluster.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLUSTER_H_ 2 | #define __CLUSTER_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | 7 | namespace nacos{ 8 | class HealthChecker { 9 | private: 10 | NacosString type; 11 | public: 12 | NacosString getType() const { return type; }; 13 | void setType(const NacosString &_type) { type = _type; }; 14 | }; 15 | class Cluster { 16 | private: 17 | NacosString name; 18 | HealthChecker healthChecker; 19 | std::map metadata; 20 | public: 21 | NacosString getName() const; 22 | 23 | void setName(const NacosString &name); 24 | 25 | HealthChecker getHealthChecker() const; 26 | 27 | void setHealthChecker(const HealthChecker &healthChecker); 28 | 29 | std::map getMetadata() const; 30 | 31 | void setMetadata(const std::map &metadata); 32 | }; 33 | }//namespace nacos 34 | 35 | #endif -------------------------------------------------------------------------------- /include/constant/NamingConstant.h: -------------------------------------------------------------------------------- 1 | #ifndef __NAMING_CONSTANT_H_ 2 | #define __NAMING_CONSTANT_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | namespace nacos{ 7 | class NamingConstant { 8 | public: 9 | static const NacosString SERVICE_NAME; 10 | 11 | static const NacosString CLUSTER_NAME; 12 | static const NacosString UDP_PORT; 13 | static const NacosString CLUSTERS; 14 | static const NacosString CLIENT_IP; 15 | static const NacosString HEALTHY_ONLY; 16 | 17 | static const NacosString HEALTHY; 18 | 19 | static const NacosString NAMESPACE_ID; 20 | 21 | static const NacosString GROUP_NAME; 22 | 23 | static const NacosString SPLITER; 24 | 25 | static const NacosString EMPTY; 26 | 27 | static const NacosString ALL_IPS; 28 | 29 | static const NacosString BEAT; 30 | 31 | static const NacosString PAGE_SIZE; 32 | static const NacosString PAGE_NO; 33 | }; 34 | }//namespace nacos 35 | 36 | #endif -------------------------------------------------------------------------------- /src/naming/selectors/RandomSelector.cpp: -------------------------------------------------------------------------------- 1 | #include "naming/selectors/RandomSelector.h" 2 | #include "src/log/Logger.h" 3 | #include "src/utils/RandomUtils.h" 4 | #include "src/utils/ParamUtils.h" 5 | 6 | namespace nacos { namespace naming { namespace selectors { 7 | 8 | std::list RandomSelector::select(const std::list &instancesToSelect){ 9 | size_t maxSvrSlot = instancesToSelect.size(); 10 | log_debug("RandomSelector::select:nr_servers%d\n", maxSvrSlot); 11 | size_t selectedServer; 12 | if (maxSvrSlot == 1) { 13 | selectedServer = 0; 14 | } else { 15 | selectedServer = RandomUtils::random(0, maxSvrSlot - 1); 16 | } 17 | log_debug("RandomSelector::select:%d\n", selectedServer); 18 | 19 | std::list result; 20 | 21 | result.push_back(ParamUtils::getNthElem(instancesToSelect, selectedServer)); 22 | 23 | return result; 24 | } 25 | 26 | } /*selectors*/ } /*naming*/ }/*nacos*/ -------------------------------------------------------------------------------- /src/crypto/MACProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/7/8. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_MACPROVIDER_H 6 | #define NACOS_SDK_CPP_MACPROVIDER_H 7 | #include "NacosString.h" 8 | #include 9 | 10 | namespace nacos { 11 | 12 | class IMAC { 13 | public: 14 | virtual void getMac(const void *k, /* secret key */ 15 | size_t lk, /* length of the key in bytes */ 16 | const void *d, /* data */ 17 | size_t ld, /* length of data in bytes */ 18 | void *out, /* output buffer, at least "t" bytes */ 19 | size_t *t) = 0; 20 | virtual ~IMAC() {}; 21 | }; 22 | 23 | class MACProvider { 24 | private: 25 | static std::map *MACRegistry; 26 | public: 27 | static void Init(); 28 | static void DeInit(); 29 | static IMAC *getMAC(int algorithm); 30 | static const int HMAC_SHA1 = 930620; 31 | }; 32 | 33 | } 34 | 35 | #endif //NACOS_SDK_CPP_MACPROVIDER_H 36 | -------------------------------------------------------------------------------- /src/naming/cache/NamingCache.h: -------------------------------------------------------------------------------- 1 | #ifndef __NAMING_CACHE_H_ 2 | #define __NAMING_CACHE_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | #include "src/naming/subscribe/EventDispatcher.h" 7 | #include "naming/ServiceInfo.h" 8 | #include "src/thread/RWLock.h" 9 | #include "naming/ChangeAdvice.h" 10 | #include "Compatibility.h" 11 | #include "NacosExceptions.h" 12 | 13 | namespace nacos{ 14 | class NamingCache { 15 | private: 16 | std::map namingList; 17 | RWLock _rwLock; 18 | EventDispatcher *_eventDispatcher; 19 | public: 20 | NamingCache(); 21 | NamingCache(EventDispatcher *eventDispatcher) { _eventDispatcher = eventDispatcher; }; 22 | ServiceInfo getServiceInfo(const NacosString &key) NACOS_THROW(NacosException); 23 | bool contains(const NacosString &key); 24 | void setServiceInfo(const NacosString &key, const ServiceInfo &info); 25 | void removeServiceInfo(const NacosString &key); 26 | }; 27 | }//namespace nacos 28 | 29 | #endif -------------------------------------------------------------------------------- /include/NacosString.h: -------------------------------------------------------------------------------- 1 | #ifndef __NACOS_STRING_H_ 2 | #define __NACOS_STRING_H_ 3 | 4 | #include 5 | #include 6 | 7 | #define NacosString std::string 8 | #define NULLSTR NacosStringOps::nullstr 9 | #define isNull NacosStringOps::isNullStr 10 | 11 | namespace nacos{ 12 | class NacosStringOps { 13 | public: 14 | static const NacosString nullstr; 15 | 16 | static bool isNullStr(const NacosString &str); 17 | 18 | template 19 | static NacosString valueOf(T val); 20 | 21 | static const NacosString STR_TRUE; 22 | static const NacosString STR_FALSE; 23 | }; 24 | 25 | template 26 | NacosString NacosStringOps::valueOf(T val) { 27 | std::ostringstream os; 28 | if (os << val) { 29 | return NacosString(os.str().c_str()); 30 | } 31 | 32 | return NULLSTR; 33 | } 34 | 35 | template<> 36 | NacosString NacosStringOps::valueOf(bool val); 37 | 38 | }//namespace nacos 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/utils/url.cpp: -------------------------------------------------------------------------------- 1 | #include "src/utils/url.h" 2 | #include 3 | 4 | namespace nacos{ 5 | NacosString urlencode(const NacosString &content) { 6 | NacosString result; 7 | CURL *curl = curl_easy_init(); 8 | char *output = NULL; 9 | if (curl) { 10 | output = curl_easy_escape(curl, content.c_str(), content.length()); 11 | } 12 | 13 | if (output) { 14 | result = output; 15 | curl_free(output); 16 | } 17 | 18 | curl_easy_cleanup(curl); 19 | return result; 20 | } 21 | 22 | NacosString urldecode(const NacosString &content) { 23 | NacosString result; 24 | CURL *curl = curl_easy_init(); 25 | char *output = NULL; 26 | if (curl) { 27 | output = curl_easy_unescape(curl, content.c_str(), content.length(), NULL); 28 | } 29 | 30 | if (output) { 31 | result = output; 32 | curl_free(output); 33 | } 34 | 35 | curl_easy_cleanup(curl); 36 | return result; 37 | } 38 | }//namespace nacos 39 | -------------------------------------------------------------------------------- /include/naming/subscribe/EventListener.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/9/24. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_EVENTLISTENER_H 6 | #define NACOS_SDK_CPP_EVENTLISTENER_H 7 | 8 | #include "NacosString.h" 9 | #include "thread/AtomicInt.h" 10 | #include "naming/ChangeAdvice.h" 11 | 12 | namespace nacos{ 13 | class EventListener { 14 | private: 15 | NacosString listenerName; 16 | AtomicInt refCount; 17 | public: 18 | EventListener() { 19 | this->listenerName = "theListener"; 20 | }; 21 | 22 | int incRef() { return refCount.inc(); }; 23 | 24 | int decRef() { return refCount.dec(); }; 25 | 26 | int refCnt() const { return refCount.get(); }; 27 | 28 | void setListenerName(const NacosString &name) { this->listenerName = name; }; 29 | 30 | NacosString getListenerName() const { return listenerName; }; 31 | 32 | virtual void receiveNamingInfo(const ServiceInfo &changeAdvice) = 0; 33 | 34 | virtual ~EventListener(); 35 | }; 36 | }//namespace nacos 37 | 38 | 39 | #endif //NACOS_SDK_CPP_EVENTLISTENER_H 40 | -------------------------------------------------------------------------------- /src/naming/beat/BeatTask.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "BeatReactor.h" 3 | #include "NacosString.h" 4 | 5 | using namespace std; 6 | 7 | namespace nacos{ 8 | BeatTask::BeatTask(BeatInfo &beatInfo, ObjectConfigData *objectConfigData) 9 | : _beatInfo(beatInfo), _objectConfigData(objectConfigData), _scheduled(false) { 10 | }; 11 | 12 | BeatInfo BeatTask::getBeatInfo() const { 13 | return _beatInfo; 14 | } 15 | 16 | void BeatTask::setBeatInfo(const BeatInfo &beatInfo) { 17 | _beatInfo = beatInfo; 18 | } 19 | 20 | void BeatTask::run() { 21 | if (!_scheduled) { 22 | delete this; 23 | return; 24 | } 25 | uint64_t now_ms = TimeUtils::getCurrentTimeInMs(); 26 | _objectConfigData->_beatReactor->_delayedThreadPool->schedule(this, now_ms + _interval); 27 | _interval = _objectConfigData->_serverProxy->sendBeat(_beatInfo); 28 | } 29 | 30 | BeatTask::~BeatTask() { 31 | NacosString taskName = getTaskName(); 32 | log_debug("[BeatTask]Removing taskObject:%s\n", taskName.c_str()); 33 | } 34 | }//namespace nacos -------------------------------------------------------------------------------- /src/config/ConcurrentDiskUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONC_DISK_UTIL_H_ 2 | #define __CONC_DISK_UTIL_H_ 3 | 4 | #include "NacosString.h" 5 | #include "NacosExceptions.h" 6 | #include "Compatibility.h" 7 | 8 | namespace nacos{ 9 | class ConcurrentDiskUtil { 10 | public: 11 | /** 12 | * get file content 13 | * 14 | * @param file file 15 | * @param charsetName charsetName 16 | * @return content 17 | * @throws IOException IOException 18 | */ 19 | static NacosString getFileContent(const NacosString &file, const NacosString &charsetName) NACOS_THROW(IOException); 20 | 21 | /** 22 | * write file content 23 | * 24 | * @param file file 25 | * @param content content 26 | * @param charsetName charsetName 27 | * @return whether write ok 28 | * @throws IOException IOException 29 | */ 30 | static bool writeFileContent(const NacosString &path, const NacosString &content, 31 | const NacosString &charsetName) NACOS_THROW(IOException); 32 | }; 33 | }//namespace nacos 34 | 35 | #endif -------------------------------------------------------------------------------- /src/constant/NamingConstant.cpp: -------------------------------------------------------------------------------- 1 | #include "constant/NamingConstant.h" 2 | 3 | namespace nacos{ 4 | const NacosString NamingConstant::SERVICE_NAME = "serviceName"; 5 | 6 | const NacosString NamingConstant::CLUSTER_NAME = "clusterName"; 7 | const NacosString NamingConstant::UDP_PORT = "udpPort"; 8 | const NacosString NamingConstant::CLUSTERS = "clusters"; 9 | 10 | const NacosString NamingConstant::CLIENT_IP = "clientIP"; 11 | const NacosString NamingConstant::HEALTHY_ONLY = "healthyOnly"; 12 | 13 | const NacosString NamingConstant::HEALTHY = "healthy"; 14 | 15 | const NacosString NamingConstant::NAMESPACE_ID = "namespaceId"; 16 | 17 | const NacosString NamingConstant::GROUP_NAME = "groupName"; 18 | 19 | const NacosString NamingConstant::SPLITER = "@@"; 20 | 21 | const NacosString NamingConstant::EMPTY = ""; 22 | 23 | const NacosString NamingConstant::ALL_IPS = "000--00-ALL_IPS--00--000"; 24 | 25 | const NacosString NamingConstant::BEAT = "beat"; 26 | 27 | const NacosString NamingConstant::PAGE_SIZE = "pageSize"; 28 | const NacosString NamingConstant::PAGE_NO = "pageNo"; 29 | }//namespace nacos -------------------------------------------------------------------------------- /src/crypto/hmac_sha1/sha/sha.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_sha.h Interface to SHA (Secure Hash Standard) functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #ifndef SHA_H_ 8 | #define SHA_H_ (1) 9 | 10 | #ifdef USE_OPENSSL 11 | #include 12 | #else 13 | 14 | /* public api for steve reid's public domain SHA-1 implementation */ 15 | /* this file is in the public domain */ 16 | 17 | /** SHA-1 Context */ 18 | typedef struct { 19 | uint32_t state[5]; 20 | /**< Context state */ 21 | uint32_t count[2]; 22 | /**< Counter */ 23 | uint8_t buffer[64]; /**< SHA-1 buffer */ 24 | } SHA1_CTX; 25 | 26 | /** SHA-1 Context (OpenSSL compat) */ 27 | typedef SHA1_CTX SHA_CTX; 28 | 29 | /** SHA-1 Digest size in bytes */ 30 | #define SHA1_DIGEST_SIZE 20 31 | /** SHA-1 Digest size in bytes (OpenSSL compat) */ 32 | #define SHA_DIGEST_LENGTH SHA1_DIGEST_SIZE 33 | 34 | void SHA1_Init(SHA1_CTX *context); 35 | 36 | void SHA1_Update(SHA1_CTX *context, const void *p, size_t len); 37 | 38 | void SHA1_Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX *context); 39 | 40 | #endif 41 | 42 | #endif // SHA_H_ 43 | -------------------------------------------------------------------------------- /src/utils/DirUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "src/utils/DirUtils.h" 5 | 6 | #if defined(__CYGWIN__) || defined(MS_WINDOWS) 7 | #define PATH_MAX 260 8 | #elif defined(linux) 9 | #include 10 | #elif defined(FreeBSD) 11 | #include 12 | #else 13 | 14 | //we don't know how to handle this situation, check if it's defined 15 | //the is not necessarily an issue, actually in most cases it will just work 16 | #warning "Unknown system or arch, trying fallback strategy. Please check if the compilation is correct" 17 | #ifndef PATH_MAX 18 | #define PATH_MAX 260 19 | #endif 20 | 21 | #endif 22 | 23 | 24 | namespace nacos{ 25 | NacosString DirUtils::getHome() { 26 | struct passwd *pw = getpwuid(getuid()); 27 | NacosString homedir = pw->pw_dir; 28 | return homedir; 29 | } 30 | 31 | NacosString DirUtils::getCwd() { 32 | char cwd[PATH_MAX]; 33 | NacosString cwds; 34 | if (getcwd(cwd, sizeof(cwd)) != NULL) { 35 | cwds = cwd; 36 | return cwds; 37 | } 38 | 39 | return NULLSTR; 40 | } 41 | }//namespace nacos 42 | -------------------------------------------------------------------------------- /include/naming/NamingMaintainService.h: -------------------------------------------------------------------------------- 1 | #ifndef __NAM_MAINTN_SVC_H_ 2 | #define __NAM_MAINTN_SVC_H_ 3 | 4 | #include 5 | #include "naming/Instance.h" 6 | #include "naming/ServiceInfo2.h" 7 | #include "NacosString.h" 8 | #include "NacosExceptions.h" 9 | #include "ListView.h" 10 | #include "Compatibility.h" 11 | 12 | namespace nacos{ 13 | class NamingMaintainService { 14 | public: 15 | virtual bool updateInstance(const NacosString &serviceName, const NacosString & groupName, const Instance &instance) NACOS_THROW(NacosException) = 0; 16 | virtual ServiceInfo2 queryService(const NacosString &serviceName, const NacosString &groupName) NACOS_THROW(NacosException) = 0; 17 | virtual bool createService(const ServiceInfo2 &service, naming::Selector *selector) NACOS_THROW(NacosException) = 0; 18 | virtual bool deleteService(const NacosString &serviceName, const NacosString &groupName) NACOS_THROW(NacosException) = 0; 19 | virtual bool updateService(const ServiceInfo2 &service, naming::Selector *selector) NACOS_THROW(NacosException) = 0; 20 | virtual ~NamingMaintainService() {}; 21 | }; 22 | }//namespace nacos 23 | 24 | #endif -------------------------------------------------------------------------------- /src/thread/DelayedThreadPool.h: -------------------------------------------------------------------------------- 1 | #ifndef __DELAYED_THREAD_POOL_H_ 2 | #define __DELAYED_THREAD_POOL_H_ 3 | 4 | #include 5 | #include 6 | #include "src/thread/ThreadPool.h" 7 | #include "src/thread/Task.h" 8 | #include "src/thread/Mutex.h" 9 | 10 | namespace nacos { 11 | 12 | class DelayedWorker; 13 | 14 | class DelayedThreadPool : public ThreadPool { 15 | private: 16 | Condition _delayTaskNotEmpty; 17 | Mutex _lockForScheduleTasks;//for _scheduledTasks 18 | std::vector< std::pair > _scheduledTasks; 19 | DelayedThreadPool(); 20 | DelayedWorker **delayTasks; 21 | volatile bool _stop_delayed_tp; 22 | public: 23 | DelayedThreadPool(const NacosString &poolName, size_t poolSize) ; 24 | ~DelayedThreadPool(); 25 | 26 | /** 27 | * schedule the execution for a task 28 | * @param t the task to run 29 | * @param futureTimeToRun the time (in ms) for the task to run 30 | */ 31 | void schedule(Task *t, long futureTimeToRun); 32 | 33 | friend class DelayedWorker; 34 | 35 | virtual void start(); 36 | 37 | virtual void stop(); 38 | }; 39 | 40 | } 41 | 42 | #endif -------------------------------------------------------------------------------- /src/utils/RandomUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef __RND_UTILS_H_ 2 | #define __RND_UTILS_H_ 3 | 4 | #include "NacosExceptions.h" 5 | #include "src/thread/ThreadLocal.h" 6 | #include "Compatibility.h" 7 | 8 | /** 9 | * RandomUtils 10 | * 11 | * @author Liu, Hanyu 12 | * get random buffer from /dev/urandom 13 | * and helper functions to get random random number 14 | */ 15 | 16 | namespace nacos{ 17 | class RandomUtils { 18 | private: 19 | static int fd; 20 | 21 | static int random_inner(); 22 | 23 | static ThreadLocal initedForThisThread; 24 | public: 25 | 26 | static void Init(); 27 | 28 | static void DeInit(); 29 | 30 | static size_t getRandomBuffer(void *dest, size_t size); 31 | 32 | /** 33 | * generates a random number ranges from begin to end (including the begin and the end) 34 | * 35 | * @param begin begin of the range (inclusive) 36 | * @param end end of the range (inclusive) 37 | * @return a long random number 38 | * @throw (NacosException) if begin >= end 39 | */ 40 | static int random(int begin, int end) NACOS_THROW(NacosException); 41 | }; 42 | }//namespace nacos 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/crypto/SignatureTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/7/8. 3 | // 4 | 5 | #ifndef SIGNATURE_TOOL 6 | #define SIGNATURE_TOOL 7 | 8 | #include "NacosString.h" 9 | #include "MACProvider.h" 10 | #include "base64/base64.h" 11 | #include "src/debug/DebugAssertion.h" 12 | 13 | namespace nacos { 14 | 15 | /** 16 | * SignatureTool 17 | * 18 | * @author Liu, Hanyu 19 | * Signature tool 20 | */ 21 | class SignatureTool { 22 | public: 23 | //Returns a base64-encoded signature string 24 | static NacosString SignWithHMAC_SHA1(const NacosString &dataToSign, const NacosString &secretKey) { 25 | IMAC *digester = MACProvider::getMAC(MACProvider::HMAC_SHA1); 26 | unsigned char signature[20]; 27 | size_t outlen = sizeof(signature); 28 | digester->getMac(secretKey.c_str(), secretKey.length(), dataToSign.c_str(), dataToSign.length(), (void*)signature, &outlen); 29 | NACOS_ASSERT(outlen == 20);//must be 20 since we're using HMAC_SHA1 30 | NacosString encoded_signature = base64_encode(signature, sizeof(signature)); 31 | return encoded_signature; 32 | } 33 | }; 34 | 35 | } 36 | #endif //NACOS_SDK_CPP_MACPROVIDER_H 37 | -------------------------------------------------------------------------------- /src/naming/beat/BeatTask.h: -------------------------------------------------------------------------------- 1 | #ifndef __BEAT_TASK_H_ 2 | #define __BEAT_TASK_H_ 3 | 4 | #include "BeatInfo.h" 5 | #include "src/naming/NamingProxy.h" 6 | #include "BeatReactor.h" 7 | #include "src/thread/ThreadPool.h" 8 | #include "src/thread/Task.h" 9 | #include "thread/AtomicInt.h" 10 | #include "src/log/Logger.h" 11 | #include "src/factory/ObjectConfigData.h" 12 | 13 | namespace nacos{ 14 | class BeatReactor; 15 | 16 | class BeatTask : public Task { 17 | private: 18 | BeatInfo _beatInfo; 19 | ObjectConfigData *_objectConfigData; 20 | bool _scheduled; 21 | uint64_t _interval;//interval for heartbeat got from the server 22 | public: 23 | BeatTask(BeatInfo &beatInfo, ObjectConfigData *objectConfigData); 24 | 25 | ~BeatTask(); 26 | 27 | void setBeatInfo(const BeatInfo &beatInfo); 28 | BeatInfo getBeatInfo() const; 29 | 30 | void run(); 31 | 32 | void setScheduled(bool scheduled) { _scheduled = scheduled; }; 33 | bool getScheduled() { return _scheduled; }; 34 | 35 | void setInterval(uint64_t interval) { _interval = interval; }; 36 | uint64_t getInterval() const { return _interval; }; 37 | }; 38 | }//namespace nacos 39 | 40 | #endif -------------------------------------------------------------------------------- /src/crypto/hmac_sha1/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Bob Liu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/constant/UtilAndComs.cpp: -------------------------------------------------------------------------------- 1 | #include "constant/UtilAndComs.h" 2 | 3 | namespace nacos{ 4 | NacosString UtilAndComs::VERSION = "Nacos-C-Client:v1.0.21";//TODO:fix nacos trunk code for cpp client 5 | 6 | NacosString UtilAndComs::ENCODING = "UTF-8"; 7 | 8 | NacosString UtilAndComs::NACOS_URL_BASE = "/v1/ns"; 9 | 10 | NacosString UtilAndComs::NACOS_URL_INSTANCE = NACOS_URL_BASE + "/instance"; 11 | 12 | int UtilAndComs::REQUEST_DOMAIN_RETRY_COUNT = 3; 13 | 14 | NacosString UtilAndComs::SERVER_ADDR_IP_SPLITER = ":"; 15 | 16 | int UtilAndComs::DEFAULT_CLIENT_BEAT_THREAD_COUNT = 4;//TODO:Calc this according to nr_processors of the host 17 | 18 | int UtilAndComs::DEFAULT_POLLING_THREAD_COUNT = 1;//TODO:Calc this according to nr_processors of the host 19 | 20 | //Underlying logic: 21 | /*int UtilAndComs::DEFAULT_CLIENT_BEAT_THREAD_COUNT = Runtime.getRuntime() 22 | .availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2 23 | : 1; 24 | 25 | int UtilAndComs::DEFAULT_POLLING_THREAD_COUNT = Runtime.getRuntime() 26 | .availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2 27 | : 1;*/ 28 | 29 | void UtilAndComs::Init() { 30 | 31 | } 32 | 33 | }//namespace nacos 34 | -------------------------------------------------------------------------------- /src/thread/RWLock.h: -------------------------------------------------------------------------------- 1 | #ifndef __RWLOCK_H_ 2 | #define __RWLOCK_H_ 3 | 4 | #include 5 | #include 6 | 7 | /* 8 | * Mutex.h 9 | * Author: Liu, Hanyu 10 | * An encapsulation of pthread_rwlock 11 | */ 12 | 13 | namespace nacos{ 14 | class RWLock { 15 | private: 16 | pthread_rwlock_t _pthread_rwlock; 17 | public: 18 | RWLock() { pthread_rwlock_init(&_pthread_rwlock, NULL); }; 19 | 20 | ~RWLock() { pthread_rwlock_destroy(&_pthread_rwlock); }; 21 | 22 | int unlock() { return pthread_rwlock_unlock(&_pthread_rwlock); }; 23 | 24 | int readLock() { return pthread_rwlock_rdlock(&_pthread_rwlock); }; 25 | 26 | int writeLock() { return pthread_rwlock_wrlock(&_pthread_rwlock); }; 27 | }; 28 | 29 | class ReadGuard { 30 | private: 31 | RWLock &_rwLock; 32 | public: 33 | ReadGuard(RWLock &rwLock) : _rwLock(rwLock) { 34 | _rwLock.readLock(); 35 | } 36 | 37 | ~ReadGuard() { _rwLock.unlock(); } 38 | }; 39 | 40 | class WriteGuard { 41 | private: 42 | RWLock &_rwLock; 43 | public: 44 | WriteGuard(RWLock &rwLock) : _rwLock(rwLock) { 45 | _rwLock.writeLock(); 46 | } 47 | 48 | ~WriteGuard() { _rwLock.unlock(); } 49 | }; 50 | }//namespace nacos 51 | 52 | #endif -------------------------------------------------------------------------------- /src/naming/beat/BeatInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef __BEAT_INFO_H_ 2 | #define __BEAT_INFO_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | 7 | /* 8 | * Copyright 1999-2018 Alibaba Group Holding Ltd. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | */ 22 | 23 | /** 24 | * @author nkorange 25 | */ 26 | namespace nacos{ 27 | class BeatInfo { 28 | public: 29 | int port; 30 | NacosString ip; 31 | double weight; 32 | NacosString serviceName; 33 | NacosString cluster; 34 | std::map metadata; 35 | volatile bool scheduled; 36 | volatile long nextHbTime; 37 | 38 | NacosString toString(); 39 | }; 40 | }//namespace nacos 41 | 42 | #endif -------------------------------------------------------------------------------- /nacos-cpp-cli.properties: -------------------------------------------------------------------------------- 1 | #!!please NOTE that the file format for this properties should be UNIX!! 2 | #specify nacos server address here(separated by ,) 3 | #serverAddr= 4 | 5 | #log path, default is ~/nacos/logs/ 6 | #nacos.log.path= 7 | 8 | #rotate size (number [+ unit], unit can be k/K m/M g/G. the size is regarded as byte if there is no unit) 9 | #nacos.log.rotateSize=100m 10 | 11 | #log level, default is ERROR 12 | #nacos.log.level=ERROR 13 | 14 | #client IP, the client will automatically detect NIC and find the best IP 15 | #but if that doesn't work, you can override it here manually 16 | #nacos.client.ip= 17 | 18 | #if the server is secured with password, you may specify it here 19 | #nacos.auth.username= 20 | #nacos.auth.password= 21 | 22 | #specify this if you are using an endpoint 23 | #endpoint= 24 | #endpointPort= 25 | 26 | #specify context path for nacos server ("nacos" by default) 27 | #nacos.server.contextpath= 28 | 29 | #advanced settings 30 | #port for udp listener (to receive service change information for subscribed services) 31 | #nacos.udp.port= 32 | 33 | #poller interval (10000 ms by default) to refresh subscribed service information from server 34 | #naming.poller.interval= 35 | 36 | #accessKey/secretKey for SPAS 37 | #accessKey= 38 | #secretKey= 39 | -------------------------------------------------------------------------------- /test/testcase/DebugTest.cpp: -------------------------------------------------------------------------------- 1 | #include "src/log/Logger.h" 2 | 3 | using namespace std; 4 | using namespace nacos; 5 | 6 | bool testDebug() { 7 | log_print(DEBUG, "print\n"); 8 | log_debug("debug\n"); 9 | log_info("info\n"); 10 | log_warn("warn\n"); 11 | log_error("error\n"); 12 | return true; 13 | } 14 | 15 | bool testVaArgs() { 16 | //log_print(DEBUG, "print\n","print","print"); 17 | log_debug("debug\n", "debug", "debug"); 18 | log_info("info\n", "info", "info"); 19 | log_warn("warn\n", "warn", "warn"); 20 | log_error("error\n", "error", "error"); 21 | return true; 22 | } 23 | 24 | bool testlogPrint() { 25 | log_print(DEBUG, "===>print %s %s %d\n", "print", "print", 9); 26 | log_print(DEBUG, "===>print %s %s %d\n", "print", "print", 9); 27 | log_print(DEBUG, "===>print %s %s %d\n", "print", "print", 9); 28 | return true; 29 | } 30 | 31 | bool testVaArgs2() { 32 | log_info("info %s %s\n", "info", "info"); 33 | log_print(DEBUG, "print %s %s %d\n", "print", "print", 9); 34 | log_debug("debug %s %s\n", "debug", "debug"); 35 | log_info("info %s %s\n", "info", "info"); 36 | log_warn("warn %s %s\n", "warn", "warn"); 37 | log_error("error %s %s %d %f\n", "error", "error", 999, 3.14); 38 | return true; 39 | } -------------------------------------------------------------------------------- /examples/setConfig.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Nacos.h" 3 | 4 | using namespace std; 5 | using namespace nacos; 6 | 7 | int main() { 8 | Properties props; 9 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848";//server address 10 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 11 | ResourceGuard _guardFactory(factory); 12 | ConfigService *n = factory->CreateConfigService(); 13 | ResourceGuard _serviceFactory(n); 14 | bool bSucc = false; 15 | NacosString ss = ""; 16 | 17 | try { 18 | bSucc = n->publishConfig("Cfg_key", NULLSTR, "Cfg_val"); 19 | int retry = 0; 20 | ss = n->getConfig("Cfg_key", NULLSTR, 1000); 21 | while (!(ss == "Cfg_val") && retry++ < 10) { 22 | ss = n->getConfig("Cfg_key", NULLSTR, 1000); 23 | } 24 | 25 | if (!(ss == "Cfg_val")) { 26 | throw NacosException(0, "getConfig() failed."); 27 | } 28 | } 29 | catch (NacosException &e) { 30 | cout << 31 | "Request failed with curl code:" << e.errorcode() << endl << 32 | "Reason:" << e.what() << endl; 33 | 34 | return -1; 35 | } 36 | cout << "Publishing Key:Cfg_key with value:Cfg_val result:" << bSucc << endl; 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /test/testcase/testMD5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "src/crypto/md5/md5.h" 4 | #include "src/debug/DebugAssertion.h" 5 | 6 | using namespace std; 7 | using namespace nacos; 8 | 9 | bool testMD5() { 10 | cout << "in function testMD5" << endl; 11 | MD5 md5; 12 | 13 | cout << "Checking md5 for \"a\"" << endl; 14 | md5.reset(); 15 | md5.update("a"); 16 | cout << "md5:" << md5.toString() << endl; 17 | SHOULD_BE_TRUE(md5.toString() == "0cc175b9c0f1b6a831c399e269772661", 18 | "NacosString \"a\" md5 should be 0cc175b9c0f1b6a831c399e269772661"); 19 | cout << "Checking md5 for \"aaaaaaa\"" << endl; 20 | md5.reset(); 21 | md5.update("aaaaaaa"); 22 | cout << "md5:" << md5.toString() << endl; 23 | SHOULD_BE_TRUE(md5.toString() == "5d793fc5b00a2348c3fb9ab59e5ca98a", 24 | "NacosString \"aaaaaaa\" md5 should be 5d793fc5b00a2348c3fb9ab59e5ca98a"); 25 | cout << "Checking md5 for \"2652451346435432\"" << endl; 26 | md5.reset(); 27 | md5.update("2652451346435432"); 28 | cout << "md5:" << md5.toString() << endl; 29 | SHOULD_BE_TRUE(md5.toString() == "69a8b79497dc611dcf9326a0b232ae55", 30 | "NacosString \"2652451346435432\" md5 should be 69a8b79497dc611dcf9326a0b232ae55"); 31 | return true; 32 | } 33 | -------------------------------------------------------------------------------- /test/testcase/testRapidJson.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/debug/DebugAssertion.h" 3 | #include "src/json/rapidjson/document.h" 4 | #include "src/json/rapidjson/writer.h" 5 | #include "src/json/rapidjson/stringbuffer.h" 6 | #include "src/naming/beat/BeatInfo.h" 7 | #include "src/json/JSON.h" 8 | 9 | using namespace std; 10 | using namespace rapidjson; 11 | using namespace nacos; 12 | 13 | bool testRapidJsonIntroduce() { 14 | // 1. 把 JSON 解析至 DOM。 15 | const char *json = "{\"project\":\"rapidjson\",\"stars\":10}"; 16 | Document d; 17 | d.Parse(json); 18 | // 2. 利用 DOM 作出修改。 19 | Value &s = d["stars"]; 20 | s.SetInt(s.GetInt() + 1); 21 | // 3. 把 DOM 转换(stringify)成 JSON。 22 | StringBuffer buffer; 23 | Writer writer(buffer); 24 | d.Accept(writer); 25 | // Output {"project":"rapidjson","stars":11} 26 | std::cout << buffer.GetString() << std::endl; 27 | 28 | Document parsedAgain; 29 | parsedAgain.Parse(buffer.GetString()); 30 | Value &s2 = parsedAgain["stars"]; 31 | int expectedtoBe11 = s2.GetInt(); 32 | SHOULD_BE_TRUE(expectedtoBe11 == 11, "There should be 11 stars"); 33 | 34 | return true; 35 | } 36 | 37 | bool testSerialize() { 38 | BeatInfo bi; 39 | bi.port = 10; 40 | cout << JSON::toJSONString(bi); 41 | return true; 42 | } -------------------------------------------------------------------------------- /src/listen/OperateItem.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPERATE_ITM_H_ 2 | #define __OPERATE_ITM_H_ 3 | 4 | #include "NacosString.h" 5 | #include "listen/Listener.h" 6 | 7 | /** 8 | * ListeningData 9 | * 10 | * @author Liu, Hanyu 11 | * Keeps track of the items to be operated on 12 | */ 13 | namespace nacos{ 14 | class OperateItem { 15 | private: 16 | NacosString tenant; 17 | NacosString dataId; 18 | NacosString group; 19 | Listener *listener; 20 | public: 21 | NacosString getDataId() const { 22 | return dataId; 23 | } 24 | 25 | NacosString getTenant() const { 26 | return tenant; 27 | } 28 | 29 | NacosString getGroup() const { 30 | return group; 31 | } 32 | 33 | Listener *getListener() const { 34 | return listener; 35 | } 36 | 37 | void setListener(Listener *listener) { 38 | this->listener = listener; 39 | } 40 | 41 | OperateItem(const NacosString &dataId, 42 | const NacosString &tenant, 43 | const NacosString &group, 44 | Listener *listener) { 45 | this->dataId = dataId; 46 | this->tenant = tenant; 47 | this->group = group; 48 | this->listener = listener; 49 | } 50 | 51 | NacosString toString() const { 52 | return tenant + ":" + group + ":" + dataId; 53 | } 54 | }; 55 | }//namespace nacos 56 | 57 | #endif -------------------------------------------------------------------------------- /src/naming/subscribe/UdpNamingServiceListener.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/9/26. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_UDPLSNR_H_ 6 | #define NACOS_SDK_CPP_UDPLSNR_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "src/factory/ObjectConfigData.h" 13 | #include "src/thread/Thread.h" 14 | #include "Compatibility.h" 15 | 16 | #define UDP_MSS 64 * 1024 17 | 18 | namespace nacos{ 19 | 20 | typedef struct { 21 | NacosString type; 22 | long lastRefTime; 23 | NacosString data; 24 | } PushPacket; 25 | 26 | class UdpNamingServiceListener { 27 | private: 28 | ObjectConfigData *_objectConfigData; 29 | volatile bool _started; 30 | int sockfd; 31 | int udpReceiverPort; 32 | struct sockaddr_in cliaddr; 33 | char receiveBuffer[UDP_MSS]; 34 | //assume the max compress ratio = 90% 35 | char uncompressedData[UDP_MSS * 10]; 36 | Thread *_listenerThread; 37 | 38 | void initializeUdpListener() NACOS_THROW(NacosException); 39 | static void *listenerThreadFunc(void *param); 40 | bool unGzip(char *inBuffer, size_t inSize); 41 | public: 42 | UdpNamingServiceListener(ObjectConfigData *objectConfigData); 43 | ~UdpNamingServiceListener(); 44 | void start(); 45 | void stop(); 46 | }; 47 | 48 | }//namespace nacos 49 | #endif //NACOS_SDK_CPP_UDPLSNR_H_ 50 | -------------------------------------------------------------------------------- /src/utils/RandomUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/utils/RandomUtils.h" 9 | 10 | namespace nacos{ 11 | int RandomUtils::fd; 12 | 13 | ThreadLocal RandomUtils::initedForThisThread(false); 14 | 15 | void RandomUtils::Init() { 16 | fd = open("/dev/urandom", O_RDONLY); 17 | } 18 | 19 | void RandomUtils::DeInit() { 20 | if (fd != 0) { 21 | close(fd); 22 | fd = 0; 23 | } 24 | } 25 | 26 | size_t RandomUtils::getRandomBuffer(void *dest, size_t size) { 27 | size_t bytes_read = 0; 28 | while (bytes_read < size) 29 | { 30 | bytes_read += read(fd, (char*)dest + bytes_read, size - bytes_read); 31 | } 32 | 33 | return bytes_read; 34 | } 35 | 36 | int RandomUtils::random_inner(){ 37 | if (!initedForThisThread.get()){ 38 | srand(time(NULL)); 39 | initedForThisThread.set(true); 40 | } 41 | return rand(); 42 | } 43 | 44 | int RandomUtils::random(int begin, int end) NACOS_THROW (NacosException) { 45 | //sanity check 46 | if (begin == end || begin > end) { 47 | throw NacosException(NacosException::INVALID_PARAM, "end must be greater than begin"); 48 | } 49 | long offset = random_inner() % (end - begin + 1); 50 | return begin + offset; 51 | } 52 | }//namespace nacos -------------------------------------------------------------------------------- /test/testcase/testUUID.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/utils//UuidUtils.h" 3 | #include "src/thread/Thread.h" 4 | 5 | using namespace std; 6 | using namespace nacos; 7 | 8 | bool testUUID() { 9 | cout << "in function testUUID" << endl; 10 | 11 | cout << "Generating UUID..." << endl; 12 | for (int i = 0; i < 100; i++) { 13 | cout << "UUID:" << UuidUtils::generateUuid() << endl; 14 | } 15 | cout << "test end..." << endl; 16 | 17 | return true; 18 | } 19 | 20 | void *UUIDThreadFunc(void *param) { 21 | Thread *thisThread = *((Thread **) param); 22 | for (int i = 0; i < 100; i++) { 23 | log_debug("Thread %s UUID: %s\n", thisThread->getThreadName().c_str(), UuidUtils::generateUuid().c_str()); 24 | } 25 | 26 | return NULL; 27 | } 28 | 29 | bool testUUIDMT() { 30 | cout << "in function testUUIDMT" << endl; 31 | 32 | cout << "Generating UUID..." << endl; 33 | 34 | Thread *threads[10] = {NULL}; 35 | for (int i = 0; i < 10; i++) { 36 | NacosString threadName = "UUIDThread-" + NacosStringOps::valueOf(i); 37 | threads[i] = new Thread(threadName, UUIDThreadFunc, (void *) &threads[i]); 38 | threads[i]->start(); 39 | } 40 | 41 | for (int i = 0; i < 10; i++) { 42 | threads[i]->join(); 43 | delete threads[i]; 44 | } 45 | 46 | cout << "test end..." << endl; 47 | 48 | return true; 49 | } 50 | -------------------------------------------------------------------------------- /src/utils/NamingUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef __NAMING_UTILS_H_ 2 | #define __NAMING_UTILS_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | #include "constant/ConfigConstant.h" 7 | #include "src/utils/ParamUtils.h" 8 | 9 | namespace nacos{ 10 | class NamingUtils { 11 | public: 12 | static NacosString getGroupedName(const NacosString &serviceName, const NacosString &groupName) { 13 | return groupName + ConfigConstant::SERVICE_INFO_SPLITER + serviceName; 14 | } 15 | 16 | static NacosString getServiceName(const NacosString &serviceNameWithGroup) { 17 | if (!ParamUtils::contains(serviceNameWithGroup, ConfigConstant::SERVICE_INFO_SPLITER)) { 18 | return serviceNameWithGroup; 19 | } 20 | std::vector splittedNameNGroup; 21 | ParamUtils::Explode(splittedNameNGroup, serviceNameWithGroup, ConfigConstant::SERVICE_INFO_SPLITER); 22 | return splittedNameNGroup[1]; 23 | } 24 | 25 | static NacosString getGroupName(const NacosString &serviceNameWithGroup) { 26 | if (!ParamUtils::contains(serviceNameWithGroup, ConfigConstant::SERVICE_INFO_SPLITER)) { 27 | return ConfigConstant::DEFAULT_GROUP; 28 | } 29 | std::vector splittedNameNGroup; 30 | ParamUtils::Explode(splittedNameNGroup, serviceNameWithGroup, ConfigConstant::SERVICE_INFO_SPLITER); 31 | return splittedNameNGroup[0]; 32 | } 33 | }; 34 | }//namespace nacos 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/debug/DebugAssertion.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_ASSERTION_H_ 2 | #define __DEBUG_ASSERTION_H_ 3 | 4 | #include 5 | #include 6 | #include "NacosString.h" 7 | 8 | namespace nacos{ 9 | #define TEST_ITEM_START { 10 | #define TEST_ITEM(testName, testfn) {(testName), (testfn)}, 11 | #define TEST_ITEM_END }; 12 | 13 | #define NACOS_ASSERT(x) \ 14 | if (!(x)) \ 15 | { \ 16 | printf("Assertion failed! file:" __FILE__":%d\n", __LINE__); \ 17 | abort(); \ 18 | } 19 | 20 | typedef bool (*TESTFN)(); 21 | 22 | typedef struct tagTestData { 23 | NacosString testName; 24 | TESTFN testFn; 25 | } TestData; 26 | 27 | #define SHOULD_BE_TRUE(assertion, message) \ 28 | do \ 29 | { \ 30 | if (!(assertion)) \ 31 | { \ 32 | cout << (message) << "...:failed" << endl; \ 33 | return false; \ 34 | } \ 35 | cout << (message) << "...:passed" << endl; \ 36 | } while(0); 37 | 38 | #define SHOULD_BE_FALSE(assertion, message) SHOULD_BE_TRUE(!(assertion), (message)) 39 | 40 | #ifdef NACOS_AUTH 41 | #define ADD_AUTH_INFO(x) \ 42 | do { \ 43 | (x)["nacos.auth.username"] = "nacos"; \ 44 | (x)["nacos.auth.password"] = "nacos"; \ 45 | } while (0) 46 | #else 47 | #define ADD_AUTH_INFO(x) 48 | #endif 49 | 50 | #ifdef NACOS_SPAS 51 | #define ADD_SPAS_INFO(x) \ 52 | do { \ 53 | (x)["secretKey"] = "nacos"; \ 54 | (x)["accessKey"] = "nacos"; \ 55 | } while (0) 56 | #else 57 | #define ADD_SPAS_INFO(x) 58 | #endif 59 | 60 | }//namespace nacos 61 | #endif -------------------------------------------------------------------------------- /src/naming/subscribe/SubscriptionPoller.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/9/26. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_SUBSCRIPTIONPOLLER_H 6 | #define NACOS_SDK_CPP_SUBSCRIPTIONPOLLER_H 7 | 8 | #include 9 | #include "src/thread/Thread.h" 10 | #include "src/naming/NamingProxy.h" 11 | #include "EventDispatcher.h" 12 | #include "src/factory/ObjectConfigData.h" 13 | 14 | namespace nacos{ 15 | struct PollingData 16 | { 17 | NacosString serviceName; 18 | NacosString groupName; 19 | NacosString clusters; 20 | volatile long nextPollTime; 21 | }; 22 | 23 | class SubscriptionPoller 24 | { 25 | private: 26 | Thread *_pollingThread; 27 | int _pollingInterval;//In ms 28 | int _udpPort;//udp receiver port 29 | volatile bool _started; 30 | ObjectConfigData *_objectConfigData; 31 | 32 | SubscriptionPoller(); 33 | 34 | static void *pollingThreadFunc(void *parm); 35 | 36 | //for polling list 37 | RWLock rwLock; 38 | std::map pollingList; 39 | public: 40 | SubscriptionPoller(ObjectConfigData *objectConfigData); 41 | bool addPollItem(const NacosString &serviceName, const NacosString &groupName, const NacosString &clusters); 42 | bool removePollItem(const NacosString &serviceName, const NacosString &groupName, const NacosString &clusters); 43 | void start(); 44 | void stop(); 45 | ~SubscriptionPoller(); 46 | 47 | }; 48 | }//namespace nacos 49 | 50 | #endif //NACOS_SDK_CPP_SUBSCRIPTIONPOLLER_H 51 | -------------------------------------------------------------------------------- /src/config/IOUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_UTILS_H_ 2 | #define __IO_UTILS_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | #include "NacosExceptions.h" 7 | #include "Compatibility.h" 8 | 9 | namespace nacos{ 10 | class IOUtils { 11 | private: 12 | public: 13 | static size_t getFileSize(const NacosString &file); 14 | 15 | static NacosString readStringFromFile(const NacosString &file, const NacosString &encoding) NACOS_THROW(IOException); 16 | 17 | static void 18 | writeStringToFile(const NacosString &file, const NacosString &data, const NacosString &encoding) NACOS_THROW(IOException); 19 | 20 | //Returns true if: 21 | //a. the file doesn't exist 22 | //b. the file is not a regular file 23 | static bool checkNotExistOrNotFile(const NacosString &pathname); 24 | 25 | //Returns true if: 26 | //a. the file doesn't exist 27 | //b. the file is not a directory 28 | static bool checkNotExistOrNotDir(const NacosString &pathname); 29 | 30 | //TODO:To provide compability across different platforms 31 | static NacosString getParentFile(const NacosString &thefile); 32 | 33 | //Upon success, return true 34 | //Upon failure, return false 35 | static bool recursivelyRemove(const NacosString &file); 36 | 37 | static bool cleanDirectory(const NacosString &file); 38 | 39 | static void recursivelyCreate(const NacosString &file); 40 | 41 | static std::list listFiles(const NacosString &path); 42 | }; 43 | }//namespace nacos 44 | 45 | #endif -------------------------------------------------------------------------------- /src/security/SecurityManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/11/28. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_SECURITYMANAGER_H 6 | #define NACOS_SDK_CPP_SECURITYMANAGER_H 7 | 8 | #include "src/config/AppConfigManager.h" 9 | #include "src/http/IHttpCli.h" 10 | #include "src/server/ServerListManager.h" 11 | #include "src/factory/ObjectConfigData.h" 12 | #include "Compatibility.h" 13 | 14 | namespace nacos { 15 | 16 | struct AccessToken { 17 | NacosString accessToken; 18 | long tokenTtl; 19 | bool globalAdmin; 20 | long lastRefTime; 21 | AccessToken() { 22 | accessToken = ""; 23 | tokenTtl = 0; 24 | globalAdmin = false; 25 | lastRefTime = 0; 26 | } 27 | }; 28 | 29 | class SecurityManager { 30 | private: 31 | ObjectConfigData *_objectConfigData; 32 | AccessToken _accessToken; 33 | void doLogin(const NacosString &serverAddr) NACOS_THROW(NacosException, NetworkException); 34 | RWLock _rwLock; 35 | volatile bool _started; 36 | static void * tokenRefreshThreadFunc(void *param); 37 | Thread *_tokenRefreshThread; 38 | void sleepWithRunStatusCheck(long _milliSecsToSleep); 39 | public: 40 | SecurityManager(ObjectConfigData *objectConfigData); 41 | ~SecurityManager(); 42 | void login() NACOS_THROW (NacosException); 43 | NacosString &getAccessToken(); 44 | void addAccessToken2Req(std::list ¶meter); 45 | void start(); 46 | void stop(); 47 | }; 48 | } 49 | 50 | #endif //NACOS_SDK_CPP_SECURITYMANAGER_H 51 | -------------------------------------------------------------------------------- /examples/listenToKeys.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Nacos.h" 3 | #include 4 | 5 | using namespace std; 6 | using namespace nacos; 7 | 8 | class MyListener : public Listener { 9 | private: 10 | int num; 11 | public: 12 | MyListener(int num) { 13 | this->num = num; 14 | } 15 | 16 | void receiveConfigInfo(const NacosString &configInfo) { 17 | cout << "===================================" << endl; 18 | cout << "Watcher" << num << endl; 19 | cout << "Watched Key UPDATED:" << configInfo << endl; 20 | cout << "===================================" << endl; 21 | } 22 | }; 23 | 24 | int main() { 25 | Properties props; 26 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 27 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 28 | ResourceGuard _guardFactory(factory); 29 | ConfigService *n = factory->CreateConfigService(); 30 | ResourceGuard _serviceFactory(n); 31 | 32 | MyListener *theListener = new MyListener(1);//You don't need to free it, since it will be deleted by the function removeListener 33 | n->addListener("dqid", NULLSTR, theListener);//All changes on the key dqid will be received by MyListener 34 | 35 | cout << "Input a character to continue" << endl; 36 | getchar(); 37 | cout << "remove listener" << endl; 38 | n->removeListener("dqid", NULLSTR, theListener);//Cancel listening 39 | getchar(); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /src/thread/ThreadPool.h: -------------------------------------------------------------------------------- 1 | #ifndef __THREAD_POOL_H_ 2 | #define __THREAD_POOL_H_ 3 | 4 | #include 5 | #include 6 | #include "Thread.h" 7 | #include "Task.h" 8 | #include "NacosString.h" 9 | #include "src/thread/Mutex.h" 10 | 11 | namespace nacos{ 12 | class DummyTask : public Task { 13 | public: 14 | DummyTask() { setTaskName("DummyTask"); }; 15 | 16 | void run() {}; 17 | }; 18 | 19 | class ThreadPool { 20 | private: 21 | NacosString _poolName; 22 | std::deque _taskList; 23 | Mutex _lock; 24 | Condition _NotEmpty; 25 | Condition _NotFull; 26 | static DummyTask _dummyTask; 27 | 28 | static void *runInThread(void *param); 29 | 30 | ThreadPool() : 31 | _poolName("CannotBeCreated"), _NotEmpty(_lock), _NotFull(_lock), _stop(true), _poolSize(0) {}; 32 | protected: 33 | std::list _threads; 34 | volatile bool _stop; 35 | size_t _poolSize; 36 | public: 37 | ThreadPool(const NacosString &poolName, size_t poolSize) : 38 | _poolName(poolName), _NotEmpty(_lock), _NotFull(_lock), _stop(true), _poolSize(poolSize) { 39 | }; 40 | 41 | ThreadPool(size_t poolSize) : 42 | _poolName("NacosCliWorkerThread"), _NotEmpty(_lock), _NotFull(_lock), _stop(true), _poolSize(poolSize) { 43 | }; 44 | 45 | virtual ~ThreadPool() {}; 46 | 47 | Task *take(); 48 | 49 | void put(Task *t); 50 | 51 | virtual void start(); 52 | 53 | virtual void stop(); 54 | }; 55 | 56 | }//namespace nacos 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/config/AppConfigManager.h: -------------------------------------------------------------------------------- 1 | #ifndef __APP_CFG_MGR_H_ 2 | #define __APP_CFG_MGR_H_ 3 | 4 | #include "NacosExceptions.h" 5 | #include "NacosString.h" 6 | #include "Properties.h" 7 | #include "Compatibility.h" 8 | 9 | namespace nacos{ 10 | 11 | class AppConfigManager { 12 | private: 13 | bool reloadable; 14 | Properties appConfig; 15 | NacosString configFile; 16 | //Cached contextpath 17 | NacosString _contextPath; 18 | 19 | volatile long _serverReqTimeout; 20 | 21 | AppConfigManager(); 22 | 23 | void checkReloadable() NACOS_THROW(NacosException); 24 | 25 | void initDefaults(); 26 | 27 | void applyConfig(Properties &rhs); 28 | 29 | public: 30 | bool nacosAuthEnabled(); 31 | 32 | long getServeReqTimeout() const { return _serverReqTimeout; }; 33 | 34 | bool isReloadable() const { return reloadable; }; 35 | 36 | AppConfigManager(Properties &props); 37 | 38 | AppConfigManager(const NacosString &configFile); 39 | 40 | size_t loadConfig(const NacosString &configFile) NACOS_THROW(NacosException); 41 | 42 | size_t loadConfig() NACOS_THROW(NacosException); 43 | 44 | void clearConfig(); 45 | 46 | const NacosString &get(const NacosString &key); 47 | 48 | bool contains(const NacosString &key) const; 49 | 50 | const Properties& getAllConfig() { return appConfig; }; 51 | 52 | const NacosString & getContextPath() const { return _contextPath; }; 53 | 54 | void set(const NacosString &key, const NacosString &value); 55 | }; 56 | }//namespace nacos 57 | 58 | #endif -------------------------------------------------------------------------------- /test/testcase/testDeleteConfig.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "factory/NacosFactoryFactory.h" 4 | #include "constant/PropertyKeyConst.h" 5 | #include "src/debug/DebugAssertion.h" 6 | #include "ResourceGuard.h" 7 | 8 | using namespace std; 9 | using namespace nacos; 10 | 11 | bool testDeleteConfig() { 12 | cout << "in function testDeleteConfig" << endl; 13 | Properties props; 14 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 15 | ADD_AUTH_INFO(props); 16 | ADD_SPAS_INFO(props); 17 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 18 | ResourceGuard _guardFactory(factory); 19 | ConfigService *n = factory->CreateConfigService(); 20 | ResourceGuard _serviceFactory(n); 21 | bool bSucc; 22 | for (int i = 5; i < 50; i++) { 23 | char key_s[200]; 24 | char val_s[200]; 25 | snprintf(key_s, sizeof(key_s), "Key%d", i); 26 | snprintf(val_s, sizeof(val_s), "v__%d", i); 27 | 28 | try { 29 | bSucc = n->removeConfig(key_s, NULLSTR); 30 | } 31 | catch (NacosException &e) { 32 | cout << 33 | "Request failed with curl code:" << e.errorcode() << endl << 34 | "Reason:" << e.what() << endl; 35 | return false; 36 | } 37 | cout << "Delete Key:" << key_s << " with value:" << val_s << " result:" << bSucc << endl; 38 | } 39 | 40 | return true; 41 | } -------------------------------------------------------------------------------- /include/constant/ConfigConstant.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_CONSTANTS_H_ 2 | #define __CONFIG_CONSTANTS_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | /** 7 | * Constant 8 | * 9 | * @author Nacos 10 | */ 11 | 12 | namespace nacos{ 13 | 14 | //Constants for config service 15 | class ConfigConstant { 16 | public: 17 | 18 | const static NacosString DEFAULT_GROUP; 19 | 20 | const static NacosString DEFAULT_CONTEXT_PATH; 21 | 22 | const static NacosString PROTOCOL_VERSION; 23 | 24 | const static NacosString GET_SERVERS_PATH; 25 | 26 | const static NacosString DATAID; 27 | 28 | const static NacosString PROBE_MODIFY_REQUEST; 29 | 30 | const static NacosString PROBE_MODIFY_RESPONSE; 31 | 32 | const static NacosString BASE_PATH; 33 | 34 | const static NacosString CONFIG_CONTROLLER_PATH; 35 | 36 | /** 37 | * second 38 | */ 39 | const static int POLLING_INTERVAL_TIME; 40 | 41 | const static NacosString ENCODE; 42 | 43 | const static int FLOW_CONTROL_THRESHOLD; 44 | 45 | const static NacosString LINE_SEPARATOR; 46 | 47 | const static NacosString WORD_SEPARATOR; 48 | 49 | const static NacosString NAMING_INSTANCE_ID_SPLITTER; 50 | 51 | const static NacosString DEFAULT_CLUSTER_NAME; 52 | 53 | const static NacosString SERVICE_INFO_SPLITER; 54 | 55 | const static NacosString FILE_SEPARATOR; 56 | 57 | const static NacosString CONFIG_NEXT_LINE; 58 | 59 | const static NacosString CONFIG_KV_SEPARATOR; 60 | 61 | const static NacosString DEFAULT_CONFIG_FILE; 62 | }; 63 | }//namespace nacos 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/naming/NacosNamingMaintainService.h: -------------------------------------------------------------------------------- 1 | #ifndef __NACOS_NAM_MTN_SVC_H_ 2 | #define __NACOS_NAM_MTN_SVC_H_ 3 | 4 | #include "naming/NamingMaintainService.h" 5 | #include "naming/Instance.h" 6 | #include "src/naming/NamingProxy.h" 7 | #include "src/http/IHttpCli.h" 8 | #include "NacosString.h" 9 | #include "Properties.h" 10 | #include "src/factory/ObjectConfigData.h" 11 | #include "Compatibility.h" 12 | 13 | namespace nacos{ 14 | 15 | /** 16 | * NacosNamingMaintainService 17 | * Maintain functions for Nacos 18 | * 19 | * @author liaochuntao 20 | * @author Liu, Hanyu 21 | * Maintain service 22 | * Special thanks to @liaochuntao 23 | */ 24 | class NacosNamingMaintainService : public NamingMaintainService { 25 | private: 26 | NacosNamingMaintainService(); 27 | ObjectConfigData *_objectConfigData; 28 | public: 29 | NacosNamingMaintainService(ObjectConfigData *objectConfigData); 30 | bool updateInstance(const NacosString &serviceName, const NacosString & groupName, const Instance &instance) NACOS_THROW(NacosException); 31 | ServiceInfo2 queryService(const NacosString &serviceName, const NacosString &groupName) NACOS_THROW(NacosException); 32 | bool createService(const ServiceInfo2 &service, naming::Selector *selector) NACOS_THROW(NacosException); 33 | bool deleteService(const NacosString &serviceName, const NacosString &groupName) NACOS_THROW(NacosException); 34 | bool updateService(const ServiceInfo2 &service, naming::Selector *selector) NACOS_THROW(NacosException); 35 | virtual ~NacosNamingMaintainService(); 36 | }; 37 | }//namespace nacos 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/factory/NacosServiceFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/8/30. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_NACOSSERVICEFACTORY_H 6 | #define NACOS_SDK_CPP_NACOSSERVICEFACTORY_H 7 | 8 | #include "factory/INacosServiceFactory.h" 9 | #include "Compatibility.h" 10 | #include "src/thread/Mutex.h" 11 | 12 | namespace nacos{ 13 | 14 | class AppConfigManager; 15 | class ObjectConfigData; 16 | 17 | class NacosServiceFactory : public INacosServiceFactory { 18 | private: 19 | NacosString configFile; 20 | Properties props; 21 | bool configIsSet; 22 | bool propsIsSet; 23 | 24 | Mutex logSysInitLock; 25 | static volatile bool logSystemInitialized; 26 | void initializeRuntimeLogSettings(AppConfigManager *_appConfigManager); 27 | 28 | void checkConfig() NACOS_THROW(InvalidFactoryConfigException); 29 | AppConfigManager *buildConfigManager(ObjectConfigData *objectConfigData); 30 | 31 | public: 32 | void setConfig(const NacosString &_configFile); 33 | 34 | void setProps(Properties &_props); 35 | 36 | virtual NamingService *CreateNamingService() NACOS_THROW(NacosException); 37 | 38 | virtual ConfigService *CreateConfigService() NACOS_THROW(NacosException); 39 | 40 | virtual NamingMaintainService *CreateNamingMaintainService() NACOS_THROW(NacosException); 41 | 42 | NacosServiceFactory(); 43 | 44 | NacosServiceFactory(const NacosString &_configFile); 45 | 46 | NacosServiceFactory(Properties &_props); 47 | 48 | virtual ~NacosServiceFactory(); 49 | }; 50 | 51 | }//namespace nacos 52 | 53 | #endif //NACOS_SDK_CPP_NACOSSERVICEFACTORY_H 54 | -------------------------------------------------------------------------------- /src/naming/cache/NamingCache.cpp: -------------------------------------------------------------------------------- 1 | #include "NamingCache.h" 2 | 3 | namespace nacos{ 4 | ServiceInfo NamingCache::getServiceInfo(const NacosString &key) NACOS_THROW(NacosException) 5 | { 6 | ReadGuard __readGuard(_rwLock); 7 | if (!contains(key)) 8 | { 9 | throw NacosException(0, "Key" + key + " doesn't exist"); 10 | } 11 | return namingList[key]; 12 | } 13 | 14 | bool NamingCache::contains(const NacosString &key) 15 | { 16 | ReadGuard __readGuard(_rwLock); 17 | return namingList.count(key) > 0; 18 | } 19 | 20 | void NamingCache::setServiceInfo(const NacosString &key, const ServiceInfo &info) 21 | { 22 | WriteGuard __writeGuard(_rwLock); 23 | if (_eventDispatcher != NULL) 24 | { 25 | ChangeAdvice changeAdvice; 26 | if (namingList.count(key) > 0) 27 | { 28 | //changeAdvice.oldServiceInfo = namingList[key]; 29 | //changeAdvice.newServiceInfo = info; 30 | } 31 | else 32 | { 33 | //changeAdvice.newServiceInfo = info; 34 | } 35 | //_eventDispatcher->notify(changeAdvice); 36 | } 37 | namingList[key] = info; 38 | } 39 | 40 | void NamingCache::removeServiceInfo(const NacosString &key) 41 | { 42 | WriteGuard __writeGuard(_rwLock); 43 | if (namingList.count(key) == 0) 44 | { 45 | return; 46 | } 47 | if (_eventDispatcher != NULL) 48 | { 49 | ChangeAdvice changeAdvice; 50 | //changeAdvice.oldServiceInfo = namingList[key]; 51 | //_eventDispatcher->notify(changeAdvice); 52 | } 53 | namingList.erase(key); 54 | } 55 | }//namespace nacos 56 | -------------------------------------------------------------------------------- /include/naming/Instance.h: -------------------------------------------------------------------------------- 1 | #ifndef __INSTANCE_H_ 2 | #define __INSTANCE_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | 7 | namespace nacos{ 8 | 9 | //a service instance 10 | class Instance { 11 | public: 12 | Instance & operator = (const Instance &rhs); 13 | bool operator == (const Instance &rhs) const; 14 | bool operator != (const Instance &rhs) const; 15 | 16 | Instance(); 17 | 18 | /** 19 | * unique id of this instance. 20 | */ 21 | NacosString instanceId; 22 | 23 | /** 24 | * instance ip 25 | */ 26 | NacosString ip; 27 | 28 | /** 29 | * instance port 30 | */ 31 | int port; 32 | 33 | /** 34 | * instance weight 35 | */ 36 | double weight; 37 | 38 | /** 39 | * instance health status 40 | */ 41 | bool healthy; 42 | 43 | /** 44 | * If instance is enabled to accept request 45 | */ 46 | bool enabled; 47 | 48 | /** 49 | * If instance is ephemeral 50 | * 51 | * @since 1.0.0 52 | */ 53 | bool ephemeral; 54 | 55 | /** 56 | * cluster information of instance 57 | */ 58 | NacosString clusterName; 59 | 60 | /** 61 | * Service information of instance 62 | */ 63 | NacosString serviceName; 64 | 65 | NacosString groupName; 66 | 67 | NacosString namespaceId; 68 | 69 | /** 70 | * user extended attributes 71 | */ 72 | std::map metadata; 73 | 74 | NacosString toString() const; 75 | NacosString toInetAddr(); 76 | }; 77 | }//namespace nacos 78 | 79 | #endif -------------------------------------------------------------------------------- /src/json/rapidjson/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "src/json/rapidjson/rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /src/thread/BlockingQueue.h: -------------------------------------------------------------------------------- 1 | #ifndef __BLOCKING_Q_H_ 2 | #define __BLOCKING_Q_H_ 3 | 4 | #include 5 | #include "src/thread/Mutex.h" 6 | /* 7 | * BlockingQueue.h 8 | * Thanks to Shuo, Chen's muduo: https://github.com/chenshuo/muduo/blob/master/muduo/base/BlockingQueue.h 9 | */ 10 | 11 | namespace nacos{ 12 | template 13 | class BlockingQueue 14 | { 15 | private: 16 | Mutex _mutex; 17 | Condition _notEmpty; 18 | Condition _notFull; 19 | std::deque _queue; 20 | size_t _maxSize; 21 | volatile bool _full; 22 | volatile bool _empty; 23 | public: 24 | 25 | bool full() { 26 | LockGuard lockguard(_mutex); 27 | return _full; 28 | }; 29 | bool empty() { 30 | LockGuard lockguard(_mutex); 31 | return _empty; 32 | }; 33 | 34 | BlockingQueue() : _mutex(), _notEmpty(_mutex), _notFull(_mutex), _maxSize(64), _full(false), _empty(true) {}; 35 | BlockingQueue(size_t queueSize) : _mutex(), _notEmpty(_mutex), _notFull(_mutex), _maxSize(queueSize), _full(false), _empty(true) {}; 36 | void enqueue(const T &data) 37 | { 38 | LockGuard lockguard(_mutex); 39 | _empty = false; 40 | while (_queue.size() == _maxSize) 41 | { 42 | _full = true; 43 | _notFull.wait(); 44 | } 45 | _queue.push_back(data); 46 | _notEmpty.notify(); 47 | } 48 | 49 | T dequeue() 50 | { 51 | LockGuard lockguard(_mutex); 52 | _full = false; 53 | while (_queue.empty()) 54 | { 55 | _empty = true; 56 | _notEmpty.wait(); 57 | } 58 | T front = _queue.front(); 59 | _queue.pop_front(); 60 | _notFull.notify(); 61 | return front; 62 | } 63 | }; 64 | }//namespace nacos 65 | 66 | #endif -------------------------------------------------------------------------------- /src/naming/subscribe/EventDispatcher.h: -------------------------------------------------------------------------------- 1 | #ifndef __EVT_DISPTCH_H_ 2 | #define __EVT_DISPTCH_H_ 3 | 4 | #include "src/thread/Thread.h" 5 | #include "src/thread/RWLock.h" 6 | #include "src/thread/BlockingQueue.h" 7 | #include "naming/subscribe/EventListener.h" 8 | #include 9 | 10 | namespace nacos{ 11 | struct NotifyData 12 | { 13 | NotifyData() { exit = false; }; 14 | bool exit; 15 | ServiceInfo serviceInfo; 16 | std::list listeners; 17 | }; 18 | 19 | //TODO:refactor to 2 types of eventDispatcher: 20 | //1. blocking mode, notify in notifier's thread 21 | //2. non-blocking mode(async), dispatcher has a blocking queue and send notify in that thread asynchronously 22 | class EventDispatcher { 23 | private: 24 | volatile bool _started; 25 | RWLock rwLock;//for observerMap 26 | std::map > observerMap; 27 | BlockingQueue notifyDataList; 28 | Thread *eventNotifier; 29 | 30 | static void *eventDispatcherThread(void *parm); 31 | 32 | bool removeListenerHelper(const NacosString &key, EventListener *eventListener, int &remainingListeners); 33 | 34 | void purgeAllListeners(); 35 | public: 36 | bool addListener(const NacosString &serviceName, const NacosString &clusters, EventListener *eventListener); 37 | bool removeListener(const NacosString &serviceName, const NacosString &clusters, EventListener *eventListener, int &remainingListeners); 38 | void notify(const ChangeAdvice &changeAdvice); 39 | void notifyDirectly(const ChangeAdvice &changeAdvice); 40 | void stop(); 41 | void start(); 42 | EventDispatcher(); 43 | ~EventDispatcher(); 44 | }; 45 | }//namespace nacos 46 | 47 | #endif -------------------------------------------------------------------------------- /src/init/Init.cpp: -------------------------------------------------------------------------------- 1 | #include "Init.h" 2 | #include "src/http/HTTPCli.h" 3 | #include "src/config/SnapShotSwitch.h" 4 | #include "src/config/JVMUtil.h" 5 | #include "naming/ServiceInfo2.h" 6 | #include "constant/UtilAndComs.h" 7 | #include "src/utils/UuidUtils.h" 8 | #include "src/utils/RandomUtils.h" 9 | #include "src/thread/Thread.h" 10 | #include "src/crypto/MACProvider.h" 11 | static nacos::Init initobj;//Implicitly call the constructors 12 | 13 | namespace nacos{ 14 | Mutex Init::initflagMutex; 15 | bool Init::inited = false; 16 | bool SnapShotSwitch::isSnapShot = true; 17 | bool JVMUtil::_isMultiInstance = false; 18 | ServiceInfo2 ServiceInfo2::nullServiceInfo2; 19 | 20 | void Init::doInit() { 21 | if (inited) { 22 | return; 23 | } 24 | { 25 | LockGuard _initGuard(initflagMutex); 26 | if (inited) { 27 | return; 28 | } 29 | 30 | Logger::Init(); 31 | MACProvider::Init(); 32 | HTTPCli::HTTP_GLOBAL_INIT(); 33 | UtilAndComs::Init(); 34 | RandomUtils::Init(); 35 | UuidUtils::Init(); 36 | Thread::Init(); 37 | ServiceInfo2::nullServiceInfo2.setNull(true); 38 | inited = true; 39 | } 40 | } 41 | 42 | void Init::doDeinit() { 43 | if (!inited) { 44 | return; 45 | } 46 | 47 | { 48 | LockGuard _initGuard(initflagMutex); 49 | if (!inited) { 50 | return; 51 | } 52 | 53 | MACProvider::DeInit(); 54 | Thread::DeInit(); 55 | UuidUtils::DeInit(); 56 | RandomUtils::DeInit(); 57 | HTTPCli::HTTP_GLOBAL_DEINIT(); 58 | Logger::deInit(); 59 | inited = false; 60 | } 61 | } 62 | 63 | }//namespace nacos 64 | -------------------------------------------------------------------------------- /test/testcase/testGetServiceNames.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "src/naming/NamingProxy.h" 6 | #include "factory/NacosFactoryFactory.h" 7 | #include "naming/Instance.h" 8 | #include "constant/ConfigConstant.h" 9 | #include "constant/UtilAndComs.h" 10 | #include "src/http/HTTPCli.h" 11 | #include "src/debug/DebugAssertion.h" 12 | #include "src/log/Logger.h" 13 | #include "NacosString.h" 14 | #include "Properties.h" 15 | #include "constant/PropertyKeyConst.h" 16 | #include "ResourceGuard.h" 17 | 18 | using namespace std; 19 | using namespace nacos; 20 | 21 | bool testGetServiceNames() { 22 | cout << "in function testGetServiceNames" << endl; 23 | Properties configProps; 24 | ADD_AUTH_INFO(configProps); 25 | ADD_SPAS_INFO(configProps); 26 | configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; 27 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(configProps); 28 | ResourceGuard _guardFactory(factory); 29 | NamingService *namingSvc = factory->CreateNamingService(); 30 | ResourceGuard _guardService(namingSvc); 31 | 32 | ListView res; 33 | try { 34 | res = namingSvc->getServiceList(1, 10); 35 | } 36 | catch (NacosException &e) { 37 | cout << "encounter exception while getting service names, raison:" << e.what() << endl; 38 | return false; 39 | } 40 | 41 | list nameList = res.getData(); 42 | for (list::const_iterator it = nameList.begin(); 43 | it != nameList.end(); it++) { 44 | cout << "serviceName:" << *it << endl; 45 | } 46 | 47 | return true; 48 | } -------------------------------------------------------------------------------- /src/constant/ConfigConstant.cpp: -------------------------------------------------------------------------------- 1 | #include "constant/ConfigConstant.h" 2 | 3 | /** 4 | * Constant 5 | * 6 | * @author Nacos 7 | */ 8 | 9 | namespace nacos{ 10 | const NacosString ConfigConstant::DEFAULT_GROUP = "DEFAULT_GROUP"; 11 | const NacosString ConfigConstant::DEFAULT_CONTEXT_PATH = "nacos"; 12 | const NacosString ConfigConstant::PROTOCOL_VERSION = "v1"; 13 | const NacosString ConfigConstant::GET_SERVERS_PATH = "ns/operator/servers"; 14 | 15 | const NacosString ConfigConstant::DATAID = "dataId"; 16 | 17 | const NacosString ConfigConstant::PROBE_MODIFY_REQUEST = "Listening-Configs"; 18 | 19 | const NacosString ConfigConstant::PROBE_MODIFY_RESPONSE = "Probe-Modify-Response"; 20 | 21 | const NacosString ConfigConstant::BASE_PATH = "/v1/cs"; 22 | 23 | const NacosString ConfigConstant::CONFIG_CONTROLLER_PATH = BASE_PATH + "/configs"; 24 | 25 | /** 26 | * second 27 | */ 28 | const int ConfigConstant::POLLING_INTERVAL_TIME = 15; 29 | 30 | const NacosString ConfigConstant::ENCODE = "UTF-8"; 31 | 32 | const int ConfigConstant::FLOW_CONTROL_THRESHOLD = 20; 33 | 34 | const NacosString ConfigConstant::LINE_SEPARATOR = "\x1"; 35 | 36 | const NacosString ConfigConstant::WORD_SEPARATOR = "\x2"; 37 | 38 | const NacosString ConfigConstant::NAMING_INSTANCE_ID_SPLITTER = "#"; 39 | 40 | const NacosString ConfigConstant::DEFAULT_CLUSTER_NAME = "DEFAULT"; 41 | 42 | const NacosString ConfigConstant::SERVICE_INFO_SPLITER = "@@"; 43 | 44 | const NacosString ConfigConstant::FILE_SEPARATOR = "/"; 45 | 46 | const NacosString ConfigConstant::CONFIG_NEXT_LINE = "\n"; 47 | 48 | const NacosString ConfigConstant::CONFIG_KV_SEPARATOR = "="; 49 | 50 | const NacosString ConfigConstant::DEFAULT_CONFIG_FILE = "nacos-cpp-cli.properties"; 51 | }//namespace nacos 52 | -------------------------------------------------------------------------------- /src/http/delegate/NoOpHttpDelegate.h: -------------------------------------------------------------------------------- 1 | #ifndef __SVR_HTTP_AGENT_H_ 2 | #define __SVR_HTTP_AGENT_H_ 3 | 4 | #include "NacosExceptions.h" 5 | #include "NacosString.h" 6 | #include "src/http/HttpDelegate.h" 7 | #include "src/factory/ObjectConfigData.h" 8 | #include "Compatibility.h" 9 | 10 | /** 11 | * NoOpHttpDelegate 12 | * 13 | * @author Liu, Hanyu 14 | * Directly send request to HttpCli without any operation 15 | */ 16 | namespace nacos{ 17 | class NoOpHttpDelegate : public HttpDelegate { 18 | private: 19 | ObjectConfigData *_objectConfigData; 20 | NacosString encoding; 21 | public: 22 | NoOpHttpDelegate(ObjectConfigData *objectConfigData); 23 | 24 | HttpResult httpGet(const NacosString &path, std::list &headers, std::list ¶mValues, 25 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 26 | 27 | HttpResult httpPost(const NacosString &path, std::list &headers, std::list ¶mValues, 28 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 29 | 30 | virtual HttpResult 31 | httpPut(const NacosString &path, std::list &headers, std::list ¶mValues, 32 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 33 | 34 | HttpResult 35 | httpDelete(const NacosString &path, std::list &headers, std::list ¶mValues, 36 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 37 | 38 | NacosString getEncode() const; 39 | 40 | virtual ~NoOpHttpDelegate() { 41 | }; 42 | }; 43 | }//namespace nacos 44 | 45 | #endif -------------------------------------------------------------------------------- /src/crypto/MACProvider.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/7/8. 3 | // 4 | 5 | #include "MACProvider.h" 6 | #include "src/crypto/hmac_sha1/hmac/hmac.h" 7 | 8 | namespace nacos { 9 | 10 | std::map *MACProvider::MACRegistry; 11 | const int MACProvider::HMAC_SHA1; 12 | 13 | class HMACSha1 : public IMAC { 14 | public: 15 | void getMac(const void *k, /* secret key */ 16 | size_t lk, /* length of the key in bytes */ 17 | const void *d, /* data */ 18 | size_t ld, /* length of data in bytes */ 19 | void *out, /* output buffer, at least "t" bytes */ 20 | size_t *t); 21 | }; 22 | 23 | void HMACSha1::getMac(const void *k, /* secret key */ 24 | size_t lk, /* length of the key in bytes */ 25 | const void *d, /* data */ 26 | size_t ld, /* length of data in bytes */ 27 | void *out, /* output buffer, at least "t" bytes */ 28 | size_t *t) { 29 | hmac_sha1((const uint8_t*)k, lk, (const uint8_t*)d, ld, (uint8_t*)out, t); 30 | } 31 | 32 | void MACProvider::Init() { 33 | MACRegistry = new std::map(); 34 | (*MACRegistry)[MACProvider::HMAC_SHA1] = new HMACSha1(); 35 | } 36 | 37 | void MACProvider::DeInit() { 38 | for (std::map::iterator it = MACRegistry->begin(); it != MACRegistry->end(); it++) { 39 | IMAC * curMACProvider = it->second; 40 | delete curMACProvider; 41 | } 42 | 43 | delete MACRegistry; 44 | } 45 | 46 | IMAC *MACProvider::getMAC(int algorithm) { 47 | if (MACRegistry->count(algorithm) > 0) { 48 | return (*MACRegistry)[algorithm]; 49 | } 50 | 51 | return NULL; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/crypto/md5/md5.h: -------------------------------------------------------------------------------- 1 | #ifndef MD5_H 2 | #define MD5_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "NacosString.h" 8 | 9 | namespace nacos{ 10 | /* Type define */ 11 | typedef unsigned char byte; 12 | typedef unsigned int uint32; 13 | 14 | using std::string; 15 | using std::ifstream; 16 | 17 | /* MD5 declaration. */ 18 | class MD5 { 19 | public: 20 | MD5(); 21 | 22 | MD5(const void *input, size_t length); 23 | 24 | MD5(const NacosString &str); 25 | 26 | MD5(ifstream &in); 27 | 28 | void update(const void *input, size_t length); 29 | 30 | void update(const NacosString &str); 31 | 32 | void update(ifstream &in); 33 | 34 | const byte *digest(); 35 | 36 | NacosString toString(); 37 | 38 | void reset(); 39 | 40 | private: 41 | void update(const byte *input, size_t length); 42 | 43 | void final(); 44 | 45 | void transform(const byte block[64]); 46 | 47 | void encode(const uint32 *input, byte *output, size_t length); 48 | 49 | void decode(const byte *input, uint32 *output, size_t length); 50 | 51 | NacosString bytesToHexString(const byte *input, size_t length); 52 | 53 | /* class uncopyable */ 54 | MD5(const MD5 &); 55 | 56 | MD5 &operator=(const MD5 &); 57 | 58 | private: 59 | uint32 _state[4]; /* state (ABCD) */ 60 | uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ 61 | byte _buffer[64]; /* input buffer */ 62 | byte _digest[16]; /* message digest */ 63 | bool _finished; /* calculate finished ? */ 64 | 65 | static const byte PADDING[64]; /* padding for calculate */ 66 | static const char HEX[16]; 67 | enum { 68 | BUFFER_SIZE = 1024 69 | }; 70 | }; 71 | }//namespace nacos 72 | 73 | #endif -------------------------------------------------------------------------------- /examples/registerInstances.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Nacos.h" 4 | 5 | using namespace std; 6 | using namespace nacos; 7 | 8 | int main() { 9 | Properties configProps; 10 | configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; 11 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(configProps); 12 | ResourceGuard _guardFactory(factory); 13 | NamingService *namingSvc = factory->CreateNamingService(); 14 | ResourceGuard _serviceFactory(namingSvc); 15 | Instance instance; 16 | instance.clusterName = "DefaultCluster"; 17 | instance.ip = "127.0.0.1"; 18 | instance.port = 2333; 19 | instance.instanceId = "1"; 20 | instance.ephemeral = true; 21 | 22 | //Registers 5 services named TestNamingService1...5 23 | try { 24 | for (int i = 0; i < 5; i++) { 25 | NacosString serviceName = "TestNamingService" + NacosStringOps::valueOf(i); 26 | instance.port = 2000 + i; 27 | namingSvc->registerInstance(serviceName, instance); 28 | } 29 | } 30 | catch (NacosException &e) { 31 | cout << "encounter exception while registering service instance, raison:" << e.what() << endl; 32 | return -1; 33 | } 34 | sleep(30); 35 | try { 36 | for (int i = 0; i < 5; i++) { 37 | NacosString serviceName = "TestNamingService" + NacosStringOps::valueOf(i); 38 | 39 | namingSvc->deregisterInstance(serviceName, "127.0.0.1", 2000 + i); 40 | sleep(1); 41 | } 42 | } 43 | catch (NacosException &e) { 44 | cout << "encounter exception while registering service instance, raison:" << e.what() << endl; 45 | return -1; 46 | } 47 | sleep(30); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /test/testcase/testSequenceProvider.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/thread/Thread.h" 3 | #include "src/utils/SequenceProvider.h" 4 | #include "src/utils/DirUtils.h" 5 | 6 | using namespace std; 7 | using namespace nacos; 8 | 9 | #define NR_THREADS 200 10 | #define GENERATION_PER_THREAD 1000 11 | 12 | int64_t sequences[GENERATION_PER_THREAD * NR_THREADS]; 13 | int tid[NR_THREADS]; 14 | 15 | SequenceProvider *sequenceProvider; 16 | 17 | void *SeqThreadFunc(void *param) { 18 | int *thread_no = (int*)param; 19 | for (int i = 0; i < GENERATION_PER_THREAD; i++) { 20 | int64_t res = sequenceProvider->next(); 21 | sequences[(*thread_no) * GENERATION_PER_THREAD + i] = res; 22 | } 23 | 24 | return NULL; 25 | } 26 | 27 | bool testSequenceProvider() { 28 | cout << "in function testSequenceProvider" << endl; 29 | 30 | cout << "Generating SEQ..." << endl; 31 | 32 | sequenceProvider = new SequenceProvider (DirUtils::getCwd() + "/test_seq.dat", 20000, 100); 33 | 34 | Thread *threads[NR_THREADS] = {NULL}; 35 | for (int i = 0; i < NR_THREADS; i++) { 36 | NacosString threadName = "SEQThread-" + NacosStringOps::valueOf(i); 37 | tid[i] = i; 38 | threads[i] = new Thread(threadName, SeqThreadFunc, (void *) &tid[i]); 39 | threads[i]->start(); 40 | } 41 | 42 | for (int i = 0; i < NR_THREADS; i++) { 43 | threads[i]->join(); 44 | delete threads[i]; 45 | } 46 | 47 | cout << "Generated." << endl; 48 | 49 | for (int i = 0; i < NR_THREADS; i++) { 50 | for (int j = 0; j < GENERATION_PER_THREAD; j++) { 51 | cout << "Thread " << i << ": sequence =\t" << sequences[i * GENERATION_PER_THREAD + j] << endl; 52 | } 53 | } 54 | 55 | cout << "test end..." << endl; 56 | 57 | return true; 58 | } 59 | -------------------------------------------------------------------------------- /src/thread/Thread.cpp: -------------------------------------------------------------------------------- 1 | #include "Thread.h" 2 | 3 | using namespace nacos; 4 | 5 | struct sigaction Thread::old_action; 6 | 7 | void Thread::Init() { 8 | struct sigaction action; 9 | 10 | action.sa_flags = 0; 11 | action.sa_handler = empty_signal_handler; 12 | sigemptyset(&action.sa_mask); 13 | 14 | sigaction(THREAD_STOP_SIGNAL, &action, &Thread::old_action); 15 | }; 16 | 17 | void Thread::DeInit() { 18 | sigaction(THREAD_STOP_SIGNAL, &Thread::old_action, NULL); 19 | }; 20 | 21 | void *Thread::threadFunc(void *param) { 22 | Thread *currentThread = (Thread *) param; 23 | currentThread->_tid = gettidv1(); 24 | 25 | try { 26 | return currentThread->_function(currentThread->_threadData); 27 | } 28 | catch (std::exception &e) { 29 | currentThread->_function = NULL; 30 | log_error("Exception happens when executing:\n"); 31 | log_error("Thread Name:%s Thread Id:%d\n", currentThread->_threadName.c_str(), currentThread->_tid); 32 | log_error("Raison:%s", e.what()); 33 | abort(); 34 | } 35 | catch (...) { 36 | currentThread->_function = NULL; 37 | log_error("Unknown exception happens when executing:\n"); 38 | log_error("Thread Name:%s Thread Id:%d\n", currentThread->_threadName.c_str(), currentThread->_tid); 39 | throw; 40 | } 41 | } 42 | 43 | void Thread::start() { 44 | _start = true; 45 | pthread_create(&_thread, NULL, threadFunc, (void *) this); 46 | } 47 | 48 | void Thread::join() { 49 | log_debug("Calling Thread::join() on %s\n", _threadName.c_str()); 50 | if (!_start) { 51 | log_debug("Thread::join() called on stopped thread for %s\n", _threadName.c_str()); 52 | return; 53 | } 54 | 55 | pthread_join(_thread, NULL); 56 | } 57 | 58 | void Thread::kill() { 59 | pthread_kill(_thread, THREAD_STOP_SIGNAL); 60 | } -------------------------------------------------------------------------------- /examples/subscribeServices.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Nacos.h" 3 | #include 4 | 5 | using namespace std; 6 | using namespace nacos; 7 | 8 | class MyServiceListener : public EventListener { 9 | private: 10 | int num; 11 | public: 12 | MyServiceListener(int num) { 13 | this->num = num; 14 | } 15 | 16 | void receiveNamingInfo(const ServiceInfo &serviceInfo){ 17 | cout << "===================================" << endl; 18 | cout << "Watcher: " << num << endl; 19 | cout << "Watched service UPDATED: " << serviceInfo.toInstanceString() << endl; 20 | cout << "===================================" << endl; 21 | 22 | } 23 | }; 24 | 25 | int main() { 26 | Properties props; 27 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 28 | //Interval for poller to check the status of subscribed services(unit:Ms), 30000 by default 29 | //Here we set it to 5000 to see the output more quick 30 | props[PropertyKeyConst::SUBSCRIPTION_POLL_INTERVAL] = "5000"; 31 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 32 | ResourceGuard _guardFactory(factory); 33 | NamingService *n = factory->CreateNamingService(); 34 | ResourceGuard _serviceFactory(n); 35 | 36 | n->subscribe("ss", new MyServiceListener(1)); 37 | cout << "Press any key to register services" << endl; 38 | getchar(); 39 | 40 | n->registerInstance("ss", "127.0.0.1", 33); 41 | n->registerInstance("ss", "127.0.0.1", 34); 42 | cout << "Press any key to deregister services" << endl; 43 | getchar(); 44 | 45 | n->deregisterInstance("ss", "127.0.0.1", 33); 46 | n->deregisterInstance("ss", "127.0.0.1", 34); 47 | cout << "All instances Unregistered, press any key to finish testing" << endl; 48 | getchar(); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /src/naming/selectors/RandomByWeightSelector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "naming/selectors/RandomByWeightSelector.h" 4 | #include "src/log/Logger.h" 5 | #include "src/utils/ParamUtils.h" 6 | #include "src/utils/RandomUtils.h" 7 | 8 | #define BASIC_WEIGHT 65536 9 | 10 | namespace nacos { namespace naming { namespace selectors { 11 | 12 | std::list RandomByWeightSelector::select(const std::list &instancesToSelect){ 13 | std::vector::const_iterator > > weightedList; 14 | std::list result; 15 | 16 | int total_weight = 0; 17 | for (std::list::const_iterator it = instancesToSelect.begin(); 18 | it != instancesToSelect.end(); it++) { 19 | if (it->weight < 1e-10) { 20 | //we consider a very small weight as 0 21 | continue; 22 | } 23 | total_weight += it->weight * BASIC_WEIGHT; 24 | log_debug("RandomByWeightSelector::select:weight for current instance:%f\n", it->weight); 25 | weightedList.push_back(std::make_pair(it->weight * BASIC_WEIGHT, it)); 26 | } 27 | if (total_weight == 0) { 28 | //no server instance is chosen 29 | return result; 30 | } 31 | log_debug("RandomByWeightSelector::select:total_weight:%d\n", total_weight); 32 | size_t selectedWeight = RandomUtils::random(0, total_weight - 1); 33 | log_debug("RandomByWeightSelector::select selected weight:%d\n", selectedWeight); 34 | 35 | std::vector::const_iterator> >::const_iterator it = weightedList.begin(); 36 | while (selectedWeight > it->second->weight * BASIC_WEIGHT) { 37 | selectedWeight -= it->second->weight * BASIC_WEIGHT; 38 | it++; 39 | } 40 | 41 | result.push_back(*it->second); 42 | return result; 43 | } 44 | 45 | } /*selectors*/ } /*naming*/ }/*nacos*/ -------------------------------------------------------------------------------- /test/testcase/testServerListManager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "src/server/ServerListManager.h" 4 | #include "src/config/NacosConfigService.h" 5 | #include "factory/NacosFactoryFactory.h" 6 | #include "ResourceGuard.h" 7 | #include "src/http/HTTPCli.h" 8 | #include "constant/PropertyKeyConst.h" 9 | #include "src/json/JSON.h" 10 | 11 | using namespace std; 12 | using namespace nacos; 13 | 14 | bool testServerListManager() { 15 | cout << "in function testServerListManager" << endl; 16 | Properties props; 17 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 18 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 19 | ResourceGuard _guardFactory(factory); 20 | ConfigService *n = factory->CreateConfigService(); 21 | ResourceGuard _serviceFactory(n); 22 | 23 | //NacosConfigService *nn = (NacosConfigService *) n; 24 | //ServerListManager *serverListManager = nn->getServerListManager(); 25 | 26 | list res;// = serverListManager->__debug(); 27 | 28 | for (list::iterator it = res.begin(); it != res.end(); it++) { 29 | NacosString key = it->getKey(); 30 | NacosString val = it->getCompleteAddress(); 31 | 32 | cout << key << ":" << endl << val << endl; 33 | } 34 | 35 | cout << "=====================cornercase========================" << endl; 36 | NacosString fakeSvr = "{\"servers\":[]}"; 37 | list result = JSON::Json2NacosServerInfo(fakeSvr); 38 | cout << "result.size == " << result.size() << endl; 39 | for (list::iterator it = result.begin(); it != result.end(); it++) { 40 | NacosString key = it->getCompleteAddress(); 41 | NacosString val = it->toString(); 42 | 43 | cout << key << ":" << endl << val << endl; 44 | } 45 | return true; 46 | } -------------------------------------------------------------------------------- /src/utils/ConfigParserUtils.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/1/9. 3 | // 4 | 5 | #include 6 | #include "ConfigParserUtils.h" 7 | #include "src/config/IOUtils.h" 8 | #include "src/utils/ParamUtils.h" 9 | #include "constant/ConfigConstant.h" 10 | using namespace std; 11 | 12 | namespace nacos { 13 | 14 | Properties ConfigParserUtils::parseConfigFile(const NacosString &file) NACOS_THROW(NacosException) { 15 | Properties parsedConfig; 16 | NacosString confContent = IOUtils::readStringFromFile(file, NULLSTR);//TODO: add encoding support 17 | 18 | vector configList; 19 | ParamUtils::Explode(configList, confContent, ConfigConstant::CONFIG_NEXT_LINE); 20 | 21 | int line = 0; 22 | for (vector::iterator it = configList.begin(); 23 | it != configList.end(); it++) { 24 | line++; 25 | NacosString trimmedLine = ParamUtils::trim(*it); 26 | if (ParamUtils::isBlank(trimmedLine)) { 27 | continue; 28 | } 29 | 30 | if (trimmedLine[0] == '#') { 31 | //skip comment 32 | continue; 33 | } 34 | 35 | if (it->find(ConfigConstant::CONFIG_KV_SEPARATOR) == std::string::npos) { 36 | throw MalformedConfigException(file, " no '=' found at line " + NacosStringOps::valueOf(line)); 37 | } 38 | 39 | vector configKV; 40 | ParamUtils::Explode(configKV, *it, ConfigConstant::CONFIG_KV_SEPARATOR); 41 | //k = v 42 | NacosString key = ParamUtils::trim(configKV[0]); 43 | if (ParamUtils::isBlank(key)) { 44 | throw MalformedConfigException(file, " key is blank at " + NacosStringOps::valueOf(line)); 45 | } 46 | 47 | if (configKV.size() == 1) { 48 | parsedConfig[key] = NULLSTR; 49 | } else { 50 | parsedConfig[key] = configKV[1]; 51 | } 52 | } 53 | 54 | return parsedConfig; 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /src/thread/Thread.h: -------------------------------------------------------------------------------- 1 | #ifndef __THREAD_H_ 2 | #define __THREAD_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "NacosString.h" 9 | #include "src/log/Logger.h" 10 | #include "src/thread/Tid.h" 11 | 12 | #define THREAD_STOP_SIGNAL SIGUSR1 13 | 14 | namespace nacos{ 15 | typedef void *(*ThreadFn)(void *); 16 | 17 | /* 18 | * Thread.h 19 | * Author: Liu, Hanyu 20 | * This is NOT like the thread class in Java! 21 | * It's just a simple encapsulation of pthread_create() and pthread_join 22 | * It doesn't have a virtual run() function, 23 | * a function pointer(ThreadFn) should be passed to the constructor so it will be used as the function pointer parameter for pthread_create 24 | */ 25 | class Thread { 26 | private: 27 | NacosString _threadName; 28 | pthread_t _thread; 29 | ThreadFn _function; 30 | //TODO:thread id 31 | TID_T _tid; 32 | bool _start; 33 | void *_threadData; 34 | 35 | Thread() {}; 36 | 37 | static void empty_signal_handler(int signum) {}; 38 | static struct sigaction old_action; 39 | public: 40 | static void Init(); 41 | static void DeInit(); 42 | 43 | void setThreadName(const NacosString &threadName) { _threadName = threadName; }; 44 | 45 | NacosString getThreadName() { return _threadName; }; 46 | 47 | static void *threadFunc(void *param); 48 | 49 | Thread(const NacosString &threadName, ThreadFn fn) 50 | : _threadName(threadName), _function(fn), _threadData(NULL) { 51 | _start = false; 52 | }; 53 | 54 | Thread(const NacosString &threadName, ThreadFn fn, void *threadData) 55 | : _threadName(threadName), _function(fn), _threadData(threadData) { 56 | _start = false; 57 | }; 58 | 59 | ~Thread() { 60 | _start = false; 61 | } 62 | 63 | void start(); 64 | 65 | void join(); 66 | 67 | void kill(); 68 | }; 69 | }//namespace nacos 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/http/delegate/NacosAuthHttpDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/12/5. 3 | // 4 | 5 | #ifndef NACOS_SDK_CPP_NACOSAUTHHTTPDELEGATE_H 6 | #define NACOS_SDK_CPP_NACOSAUTHHTTPDELEGATE_H 7 | 8 | #include "NacosExceptions.h" 9 | #include "NacosString.h" 10 | #include "src/http/HttpDelegate.h" 11 | #include "src/factory/ObjectConfigData.h" 12 | #include "Compatibility.h" 13 | 14 | /** 15 | * NoOpHttpDelegate 16 | * 17 | * @author Liu, Hanyu 18 | * Send a request to the server with authentication header 19 | */ 20 | namespace nacos{ 21 | class NacosAuthHttpDelegate : public HttpDelegate { 22 | private: 23 | ObjectConfigData *_objectConfigData; 24 | NacosString encoding; 25 | public: 26 | NacosAuthHttpDelegate(ObjectConfigData *objectConfigData); 27 | 28 | HttpResult httpGet(const NacosString &path, std::list &headers, std::list ¶mValues, 29 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 30 | 31 | HttpResult httpPost(const NacosString &path, std::list &headers, std::list ¶mValues, 32 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 33 | 34 | virtual HttpResult 35 | httpPut(const NacosString &path, std::list &headers, std::list ¶mValues, 36 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 37 | 38 | HttpResult 39 | httpDelete(const NacosString &path, std::list &headers, std::list ¶mValues, 40 | const NacosString &encoding, long readTimeoutMs) NACOS_THROW(NetworkException); 41 | 42 | NacosString getEncode() const; 43 | 44 | virtual ~NacosAuthHttpDelegate() { 45 | }; 46 | }; 47 | }//namespace nacos 48 | 49 | #endif //NACOS_SDK_CPP_NACOSAUTHHTTPDELEGATE_H 50 | -------------------------------------------------------------------------------- /src/config/LocalSnapshotManager.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOCAL_SNAPSHOT_MGR_H_ 2 | #define __LOCAL_SNAPSHOT_MGR_H_ 3 | 4 | #include "NacosString.h" 5 | #include "NacosExceptions.h" 6 | #include "src/config/AppConfigManager.h" 7 | #include "Compatibility.h" 8 | 9 | /** 10 | * Snapshot/Failover manager 11 | * 12 | * @author Nacos 13 | */ 14 | 15 | namespace nacos{ 16 | class LocalSnapshotManager { 17 | private: 18 | AppConfigManager *_appCfgMgr; 19 | NacosString LOCAL_SNAPSHOT_PATH; 20 | NacosString LOCAL_FAILOVER_PATH; 21 | public: 22 | 23 | LocalSnapshotManager(AppConfigManager *appConfigManager); 24 | 25 | NacosString getFailover(const NacosString &serverName, const NacosString &dataId, const NacosString &group, 26 | const NacosString &tenant); 27 | 28 | /** 29 | * Accuire local cache content, returns NULLSTR when the file does not exist or an exception is thrown 30 | * 获取本地缓存文件内容。NULL表示没有本地文件或抛出异常。 31 | */ 32 | NacosString getSnapshot(const NacosString &name, const NacosString &dataId, const NacosString &group, 33 | const NacosString &tenant); 34 | 35 | NacosString readFile(const NacosString &file) NACOS_THROW(IOException); 36 | 37 | void saveSnapshot(const NacosString &envName, const NacosString &dataId, const NacosString &group, 38 | const NacosString &tenant, const NacosString &config); 39 | 40 | /** 41 | * Purge all cached files in snapshot directory 42 | * 清除snapshot目录下所有缓存文件。 43 | */ 44 | void cleanAllSnapshot(); 45 | 46 | void cleanEnvSnapshot(const NacosString &envName); 47 | 48 | NacosString 49 | getFailoverFile(const NacosString &serverName, const NacosString &dataId, const NacosString &group, 50 | const NacosString &tenant); 51 | 52 | NacosString getSnapshotFile(const NacosString &envName, const NacosString &dataId, const NacosString &group, 53 | const NacosString &tenant); 54 | }; 55 | }//namespace nacos 56 | 57 | #endif -------------------------------------------------------------------------------- /src/utils/NetUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "NetUtils.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define HOST_AND_LEN 250 12 | 13 | namespace nacos{ 14 | 15 | NacosString NetUtils::getHostIp() NACOS_THROW(NacosException){ 16 | 17 | struct ifaddrs *ifaddr, *ifa; 18 | int s; 19 | char host[NI_MAXHOST]; 20 | 21 | if (getifaddrs(&ifaddr) == -1) 22 | { 23 | throw NacosException(NacosException::UNABLE_TO_GET_HOST_IP, "Failed to get IF address"); 24 | } 25 | 26 | 27 | for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) 28 | { 29 | log_debug("iterating on iface=%s\n", ifa->ifa_name); 30 | if (ifa->ifa_addr == NULL || !(ifa->ifa_addr->sa_family==AF_INET)) { 31 | continue; 32 | } 33 | 34 | if((strcmp(ifa->ifa_name,"lo")==0)) { 35 | continue; 36 | } 37 | 38 | s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in),host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); 39 | if (s != 0) { 40 | freeifaddrs(ifaddr); 41 | throw NacosException(NacosException::UNABLE_TO_GET_HOST_IP, "Failed to get IF address"); 42 | } 43 | 44 | log_debug("selected iface=%s ip=%s\n", ifa->ifa_name, host); 45 | freeifaddrs(ifaddr); 46 | return host; 47 | } 48 | //Usually the program will not run to here 49 | throw NacosException(NacosException::UNABLE_TO_GET_HOST_IP, "Failed to get IF address"); 50 | } 51 | 52 | NacosString NetUtils::getHostName() NACOS_THROW(NacosException) 53 | { 54 | char hostname[HOST_AND_LEN]; 55 | 56 | int res = gethostname(hostname, HOST_AND_LEN); 57 | if (res == 0) { 58 | return NacosString(hostname); 59 | } 60 | 61 | throw NacosException(NacosException::UNABLE_TO_GET_HOST_NAME, "Failed to get hostname, errno = " + NacosStringOps::valueOf(errno)); 62 | } 63 | 64 | }//namespace nacos 65 | -------------------------------------------------------------------------------- /src/naming/Instance.cpp: -------------------------------------------------------------------------------- 1 | #include "naming/Instance.h" 2 | #include "src/utils/ParamUtils.h" 3 | #include "src/log/Logger.h" 4 | 5 | namespace nacos{ 6 | Instance::Instance() { 7 | weight = (double)1; 8 | healthy = true; 9 | enabled = true; 10 | ephemeral = true; 11 | instanceId = ""; 12 | ip = ""; 13 | clusterName = ""; 14 | serviceName = ""; 15 | port = 0; 16 | } 17 | 18 | NacosString Instance::toString() const{ 19 | return "instanceId:" + instanceId + " ip:" + ip + " port:" + NacosStringOps::valueOf(port) + 20 | " weight:" + NacosStringOps::valueOf(weight) + " healthy:" + NacosStringOps::valueOf(healthy) + 21 | " enabled:" + NacosStringOps::valueOf(enabled) + " ephemeral:" + NacosStringOps::valueOf(ephemeral) + 22 | " clusterName:" + clusterName + " serviceName:" + serviceName + " metadata:{" + 23 | ParamUtils::Implode(metadata) + "}"; 24 | } 25 | 26 | NacosString Instance::toInetAddr() { 27 | return ip + ":" + NacosStringOps::valueOf(port); 28 | } 29 | 30 | Instance & Instance::operator = (const Instance &rhs) 31 | { 32 | this->instanceId = rhs.instanceId; 33 | this->ip = rhs.ip; 34 | this->port = rhs.port; 35 | this->weight = rhs.weight; 36 | this->healthy = rhs.healthy; 37 | this->enabled = rhs.enabled; 38 | this->ephemeral = rhs.ephemeral; 39 | this->clusterName = rhs.clusterName; 40 | this->metadata = rhs.metadata; 41 | return *this; 42 | } 43 | 44 | bool Instance::operator != (const Instance &rhs) const 45 | { 46 | return !operator==(rhs); 47 | } 48 | bool Instance::operator == (const Instance &rhs) const 49 | { 50 | return 51 | this->instanceId == rhs.instanceId && 52 | this->ip == rhs.ip && 53 | this->port == rhs.port && 54 | this->weight == rhs.weight && 55 | this->healthy == rhs.healthy && 56 | this->enabled == rhs.enabled && 57 | this->ephemeral == rhs.ephemeral && 58 | this->clusterName == rhs.clusterName && 59 | this->metadata == rhs.metadata; 60 | } 61 | }//namespace nacos 62 | -------------------------------------------------------------------------------- /test/testcase/testPublishConfigWithHttpPrefix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "factory/NacosFactoryFactory.h" 6 | #include "ResourceGuard.h" 7 | #include "constant/PropertyKeyConst.h" 8 | #include "src/debug/DebugAssertion.h" 9 | #include "src/log/Logger.h" 10 | 11 | using namespace std; 12 | using namespace nacos; 13 | 14 | bool testPublishConfigWithHttpPrefix() { 15 | cout << "in function testPublishConfigWithHttpPrefix" << endl; 16 | Properties props; 17 | props[PropertyKeyConst::SERVER_ADDR] = "htTp://localhost:8848,HtTP://127.0.0.1:8848"; 18 | ADD_AUTH_INFO(props); 19 | ADD_SPAS_INFO(props); 20 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 21 | ResourceGuard _guardFactory(factory); 22 | ConfigService *n = factory->CreateConfigService(); 23 | ResourceGuard _serviceFactory(n); 24 | bool bSucc; 25 | for (int i = 0; i < 50; i++) { 26 | char key_s[200]; 27 | char val_s[200]; 28 | snprintf(key_s, sizeof(key_s), "Key%d", i); 29 | snprintf(val_s, sizeof(val_s), "v__%d", i); 30 | NacosString ss = ""; 31 | 32 | try { 33 | bSucc = n->publishConfig(key_s, NULLSTR, val_s); 34 | int retry = 0; 35 | while (!(ss == val_s) && retry++ < 10) { 36 | sleep(1); 37 | try { 38 | ss = n->getConfig(key_s, NULLSTR, 1000); 39 | } catch (NacosException &e) { } 40 | } 41 | n->removeConfig(key_s, NULLSTR); 42 | 43 | if (!(ss == val_s)) { 44 | throw NacosException(0, "getConfig() failed."); 45 | } 46 | } 47 | catch (NacosException &e) { 48 | cout << 49 | "Request failed with curl code:" << e.errorcode() << endl << 50 | "Reason:" << e.what() << endl; 51 | 52 | return false; 53 | } 54 | cout << "Publishing Key:" << key_s << " with value:" << val_s << " result:" << bSucc << endl; 55 | } 56 | 57 | return true; 58 | } -------------------------------------------------------------------------------- /src/crypto/base64/base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Base64 encoding/decoding (RFC1341) 3 | * Copyright (c) 2005-2011, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | // 2016-12-12 - Gaspard Petit : Slightly modified to return a std::string 10 | // instead of a buffer allocated with malloc. 11 | 12 | #include 13 | 14 | namespace nacos { 15 | 16 | 17 | static const unsigned char base64_table[65] = 18 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 19 | 20 | /** 21 | * base64_encode - Base64 encode 22 | * @src: Data to be encoded 23 | * @len: Length of the data to be encoded 24 | * @out_len: Pointer to output length variable, or %NULL if not used 25 | * Returns: Allocated buffer of out_len bytes of encoded data, 26 | * or empty string on failure 27 | */ 28 | static std::string base64_encode(const unsigned char *src, size_t len) 29 | { 30 | unsigned char *out, *pos; 31 | const unsigned char *end, *in; 32 | 33 | size_t olen; 34 | 35 | olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */ 36 | 37 | if (olen < len) 38 | return std::string(); /* integer overflow */ 39 | 40 | std::string outStr; 41 | outStr.resize(olen); 42 | out = (unsigned char*)&outStr[0]; 43 | 44 | end = src + len; 45 | in = src; 46 | pos = out; 47 | while (end - in >= 3) { 48 | *pos++ = base64_table[in[0] >> 2]; 49 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; 50 | *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; 51 | *pos++ = base64_table[in[2] & 0x3f]; 52 | in += 3; 53 | } 54 | 55 | if (end - in) { 56 | *pos++ = base64_table[in[0] >> 2]; 57 | if (end - in == 1) { 58 | *pos++ = base64_table[(in[0] & 0x03) << 4]; 59 | *pos++ = '='; 60 | } 61 | else { 62 | *pos++ = base64_table[((in[0] & 0x03) << 4) | 63 | (in[1] >> 4)]; 64 | *pos++ = base64_table[(in[1] & 0x0f) << 2]; 65 | } 66 | *pos++ = '='; 67 | } 68 | 69 | return outStr; 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /test/testcase/testPublishConfig.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "factory/NacosFactoryFactory.h" 6 | #include "ResourceGuard.h" 7 | #include "constant/PropertyKeyConst.h" 8 | #include "src/debug/DebugAssertion.h" 9 | #include "src/log/Logger.h" 10 | 11 | using namespace std; 12 | using namespace nacos; 13 | 14 | bool testPublishConfig() { 15 | cout << "in function testPublishConfig" << endl; 16 | Properties props; 17 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 18 | ADD_AUTH_INFO(props); 19 | ADD_SPAS_INFO(props); 20 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 21 | ResourceGuard _guardFactory(factory); 22 | ConfigService *n = factory->CreateConfigService(); 23 | ResourceGuard _serviceFactory(n); 24 | bool bSucc; 25 | for (int i = 0; i < 50; i++) { 26 | char key_s[200]; 27 | char val_s[200]; 28 | snprintf(key_s, sizeof(key_s), "Key%d", i); 29 | snprintf(val_s, sizeof(val_s), "v__%d", i); 30 | NacosString ss = ""; 31 | 32 | try { 33 | bSucc = n->publishConfig(key_s, NULLSTR, val_s); 34 | int retry = 0; 35 | while (!(ss == val_s) && retry++ < 10) { 36 | sleep(1); 37 | try { 38 | ss = n->getConfig(key_s, NULLSTR, 1000); 39 | } catch (NacosException & ignore) { 40 | //getConfig may throw 404, but that doesn't matter 41 | } 42 | } 43 | 44 | if (!(ss == val_s)) { 45 | throw NacosException(0, "getConfig() failed."); 46 | } 47 | } 48 | catch (NacosException &e) { 49 | cout << 50 | "Request failed with curl code:" << e.errorcode() << endl << 51 | "Reason:" << e.what() << endl; 52 | 53 | return false; 54 | } 55 | cout << "Publishing Key:" << key_s << " with value:" << val_s << " result:" << bSucc << endl; 56 | } 57 | 58 | return true; 59 | } -------------------------------------------------------------------------------- /test/testcase/testDeleteListenedKeys.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "factory/NacosFactoryFactory.h" 6 | #include "ResourceGuard.h" 7 | #include "listen/Listener.h" 8 | #include "constant/PropertyKeyConst.h" 9 | #include "src/debug/DebugAssertion.h" 10 | #include "src/log/Logger.h" 11 | 12 | using namespace std; 13 | using namespace nacos; 14 | 15 | class MyListener : public Listener { 16 | private: 17 | int num; 18 | public: 19 | MyListener(int num) { 20 | this->num = num; 21 | } 22 | 23 | void receiveConfigInfo(const NacosString &configInfo) { 24 | cout << "===================================" << endl; 25 | cout << "Watcher" << num << endl; 26 | cout << "Watched Key UPDATED:" << configInfo << endl; 27 | cout << "===================================" << endl; 28 | } 29 | }; 30 | 31 | bool testRemoveKeyBeingWatched() { 32 | cout << "in function testRemoveKeyBeingWatched" << endl; 33 | Properties props; 34 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 35 | ADD_AUTH_INFO(props); 36 | ADD_SPAS_INFO(props); 37 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 38 | ResourceGuard _guardFactory(factory); 39 | ConfigService *n = factory->CreateConfigService(); 40 | ResourceGuard _serviceFactory(n); 41 | n->publishConfig("RemovedWhileWatching", NULLSTR, "dummyContent"); 42 | 43 | MyListener *theListener = new MyListener(1); 44 | n->addListener("RemovedWhileWatching", NULLSTR, theListener); 45 | 46 | sleep(2); 47 | cout << "remove key" << endl; 48 | n->removeConfig("RemovedWhileWatching", NULLSTR); 49 | sleep(2); 50 | cout << "set key" << endl; 51 | n->publishConfig("RemovedWhileWatching", NULLSTR, "dummyContent1"); 52 | sleep(2); 53 | cout << "remove key" << endl; 54 | n->removeConfig("RemovedWhileWatching", NULLSTR); 55 | cout << "Hold for 30 secs" << endl; 56 | sleep(30); 57 | n->removeListener("RemovedWhileWatching", NULLSTR, theListener); 58 | cout << "remove listener2" << endl; 59 | cout << "test successful" << endl; 60 | 61 | return true; 62 | } -------------------------------------------------------------------------------- /src/naming/NacosNamingMaintainService.cpp: -------------------------------------------------------------------------------- 1 | #include "src/naming/NacosNamingMaintainService.h" 2 | #include "src/security/SecurityManager.h" 3 | #include "constant/ConfigConstant.h" 4 | 5 | using namespace std; 6 | 7 | namespace nacos{ 8 | 9 | NacosNamingMaintainService::NacosNamingMaintainService(ObjectConfigData *objectConfigData) { 10 | _objectConfigData = objectConfigData; 11 | if (_objectConfigData->_appConfigManager->nacosAuthEnabled()) { 12 | _objectConfigData->_securityManager->login(); 13 | _objectConfigData->_securityManager->start(); 14 | } 15 | } 16 | 17 | bool NacosNamingMaintainService::updateInstance 18 | ( 19 | const NacosString &serviceName, 20 | const NacosString & groupName, 21 | const Instance &instance 22 | ) NACOS_THROW(NacosException) { 23 | Instance paramInstance = instance; 24 | paramInstance.serviceName = serviceName; 25 | paramInstance.groupName = groupName; 26 | return _objectConfigData->_serverProxy->updateServiceInstance(paramInstance); 27 | } 28 | 29 | ServiceInfo2 NacosNamingMaintainService::queryService 30 | ( 31 | const NacosString &serviceName, 32 | const NacosString &groupName 33 | ) NACOS_THROW(NacosException) { 34 | return _objectConfigData->_serverProxy->getServiceInfo(serviceName, groupName); 35 | } 36 | 37 | bool NacosNamingMaintainService::createService(const ServiceInfo2 &service, naming::Selector *selector) NACOS_THROW(NacosException) { 38 | ServiceInfo2 parmServiceInfo = service; 39 | if (!parmServiceInfo.isGroupNameSet()) { 40 | parmServiceInfo.setGroupName(ConfigConstant::DEFAULT_GROUP); 41 | } 42 | return _objectConfigData->_serverProxy->createServiceInfo(parmServiceInfo, selector); 43 | } 44 | 45 | bool NacosNamingMaintainService::deleteService(const NacosString &serviceName, const NacosString &groupName) NACOS_THROW(NacosException) { 46 | return _objectConfigData->_serverProxy->deleteServiceInfo(serviceName, groupName); 47 | } 48 | 49 | bool NacosNamingMaintainService::updateService(const ServiceInfo2 &service, naming::Selector *selector) NACOS_THROW(NacosException) { 50 | return _objectConfigData->_serverProxy->updateServiceInfo(service, selector); 51 | } 52 | 53 | NacosNamingMaintainService::~NacosNamingMaintainService() { 54 | delete _objectConfigData; 55 | } 56 | 57 | }//namespace nacos 58 | -------------------------------------------------------------------------------- /src/factory/ObjectConfigData.h: -------------------------------------------------------------------------------- 1 | #ifndef __OBJ_CFG_DATA_H_ 2 | #define __OBJ_CFG_DATA_H_ 3 | 4 | #include "naming/NamingService.h" 5 | #include "config/ConfigService.h" 6 | #include "NacosExceptions.h" 7 | #include "Compatibility.h" 8 | #include 9 | 10 | namespace nacos{ 11 | class HttpDelegate; 12 | class IHttpCli; 13 | class NamingProxy; 14 | class BeatReactor; 15 | class EventDispatcher; 16 | class SubscriptionPoller; 17 | class AppConfigManager; 18 | class ServerListManager; 19 | class ClientWorker; 20 | class LocalSnapshotManager; 21 | class SecurityManager; 22 | class UdpNamingServiceListener; 23 | class HostReactor; 24 | class ConfigProxy; 25 | template class SequenceProvider; 26 | 27 | enum FactoryType { 28 | CONFIG = 0, 29 | NAMING = 1, 30 | MAINTAIN = 2 31 | }; 32 | 33 | class ObjectConfigData { 34 | private: 35 | FactoryType factoryType; 36 | void destroyConfigService(); 37 | void destroyNamingService(); 38 | void destroyMaintainService(); 39 | //These functions are designed to prevent coding problems 40 | //(i.e.: forget to initialize HttpDelegate for a ConfigService) rather than run-time errors 41 | void checkConfigService() NACOS_THROW(NacosException); 42 | void checkNamingService() NACOS_THROW(NacosException); 43 | void checkMaintainService() NACOS_THROW(NacosException); 44 | NacosString objectId; 45 | public: 46 | const NacosString &getObjectId() const { return objectId; }; 47 | ObjectConfigData(FactoryType theFactoryType); 48 | void checkAssembledObject() NACOS_THROW(NacosException); 49 | ~ObjectConfigData(); 50 | NacosString name; 51 | NacosString encoding; 52 | HttpDelegate *_httpDelegate; 53 | IHttpCli *_httpCli; 54 | NamingProxy *_serverProxy; 55 | BeatReactor *_beatReactor; 56 | EventDispatcher *_eventDispatcher; 57 | SubscriptionPoller *_subscriptionPoller; 58 | AppConfigManager *_appConfigManager; 59 | ServerListManager *_serverListManager; 60 | ClientWorker *_clientWorker; 61 | LocalSnapshotManager *_localSnapshotManager; 62 | SecurityManager *_securityManager; 63 | UdpNamingServiceListener *_udpNamingServiceListener; 64 | HostReactor *_hostReactor; 65 | SequenceProvider *_sequenceProvider; 66 | ConfigProxy *_configProxy; 67 | }; 68 | }//namespace nacos 69 | 70 | #endif -------------------------------------------------------------------------------- /src/naming/cache/ChangeAdvice.cpp: -------------------------------------------------------------------------------- 1 | #include "naming/ChangeAdvice.h" 2 | 3 | using namespace std; 4 | 5 | namespace nacos{ 6 | ChangeAdvice::ChangeAdvice() 7 | { 8 | added = false; 9 | modified = false; 10 | removed = false; 11 | //addedInstances.clear(); 12 | //removedInstances.clear(); 13 | //modifiedInstances.clear(); 14 | } 15 | 16 | ChangeAdvice::~ChangeAdvice() 17 | { 18 | } 19 | 20 | void ChangeAdvice::compareChange 21 | ( 22 | ServiceInfo &oldInfo, 23 | ServiceInfo &newInfo, 24 | ChangeAdvice &changeAdvice 25 | ) 26 | { 27 | map oldInstanceList; 28 | map newInstanceList; 29 | for (list::iterator it = oldInfo.getHostsNocopy()->begin(); 30 | it != oldInfo.getHostsNocopy()->end(); it++) 31 | { 32 | oldInstanceList[it->toInetAddr()] = *it; 33 | } 34 | 35 | for (list::iterator it = newInfo.getHostsNocopy()->begin(); 36 | it != newInfo.getHostsNocopy()->end(); it++) 37 | { 38 | newInstanceList[it->toInetAddr()] = *it; 39 | } 40 | 41 | //find removed instances 42 | for (map::iterator it = oldInstanceList.begin(); 43 | it != oldInstanceList.end(); it++) 44 | { 45 | if (newInstanceList.count(it->first) == 0) 46 | { 47 | changeAdvice.removed = true; 48 | //changeAdvice.removedInstances.push_back(it->second); 49 | } 50 | else//find modified instances 51 | { 52 | //the item exists in both Lists, compare the content between these 2 53 | if (it->second != newInstanceList[it->first]) 54 | { 55 | changeAdvice.modified = true; 56 | //changeAdvice.modifiedInstances.push_back(newInstanceList[it->first]); 57 | } 58 | 59 | } 60 | } 61 | 62 | //find added instances 63 | for (map::iterator it = newInstanceList.begin(); 64 | it != newInstanceList.end(); it++) 65 | { 66 | if (oldInstanceList.count(it->first) == 0) 67 | { 68 | changeAdvice.added = true; 69 | //changeAdvice.addedInstances.push_back(it->second); 70 | } 71 | } 72 | } 73 | 74 | NacosString ChangeAdvice::toString() 75 | { 76 | return "Unimplemented";//trivial function 77 | } 78 | }//namespace nacos -------------------------------------------------------------------------------- /src/naming/subscribe/HostReactor.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2021/1/7. 3 | // 4 | 5 | #include "HostReactor.h" 6 | #include "src/json/JSON.h" 7 | #include "src/utils/NamingUtils.h" 8 | #include "src/naming/subscribe/EventDispatcher.h" 9 | 10 | namespace nacos { 11 | 12 | HostReactor::HostReactor(ObjectConfigData *objectConfigData) { 13 | _objectConfigData = objectConfigData; 14 | } 15 | 16 | void HostReactor::processServiceJson(const NacosString &json) { 17 | ServiceInfo serviceInfo = JSON::JsonStr2ServiceInfo(json); 18 | 19 | NacosString name = NamingUtils::getGroupedName(serviceInfo.getName(), serviceInfo.getGroupName()); 20 | NacosString key = ServiceInfo::getKey(name, serviceInfo.getClusters()); 21 | ServiceInfo oldServiceInfo; 22 | bool newServiceInfo = false; 23 | { 24 | WriteGuard _writeGuard(rwLock); 25 | if (serviceInfoMap.count(key) == 0) { 26 | if (serviceInfo.ipCount()==0) { 27 | log_warn("hosts got from server is empty.\n"); 28 | return; 29 | } 30 | serviceInfoMap[key] = serviceInfo; 31 | newServiceInfo = true; 32 | } else { 33 | oldServiceInfo = serviceInfoMap[key]; 34 | if (oldServiceInfo.getLastRefTime() >= serviceInfo.getLastRefTime()) { 35 | log_warn("ServiceInfo got from server is older than the one in client.\n"); 36 | return; 37 | } 38 | serviceInfoMap[key] = serviceInfo;//update local service info to the new one 39 | } 40 | } 41 | ChangeAdvice changeAdvice; 42 | changeAdvice.key = key; 43 | if (newServiceInfo) { 44 | changeAdvice.added = true; 45 | changeAdvice.newServiceInfo = serviceInfo; 46 | _objectConfigData->_eventDispatcher->notifyDirectly(changeAdvice); 47 | } else {//service info is updated 48 | ChangeAdvice::compareChange(oldServiceInfo, serviceInfo, changeAdvice); 49 | log_debug("Change status:modified:%d added:%d removed:%d\n", changeAdvice.modified, changeAdvice.added, 50 | changeAdvice.removed); 51 | if (changeAdvice.modified || changeAdvice.added || changeAdvice.removed) { 52 | //asm volatile("int $3"); 53 | changeAdvice.newServiceInfo = serviceInfo; 54 | _objectConfigData->_eventDispatcher->notifyDirectly(changeAdvice); 55 | } 56 | } 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/http/delegate/NoOpHttpDelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "NoOpHttpDelegate.h" 2 | 3 | using namespace std; 4 | 5 | namespace nacos{ 6 | NacosString NoOpHttpDelegate::getEncode() const { 7 | return encoding; 8 | } 9 | 10 | NoOpHttpDelegate::NoOpHttpDelegate 11 | ( 12 | ObjectConfigData *objectConfigData 13 | ) { 14 | _objectConfigData = objectConfigData; 15 | } 16 | 17 | HttpResult NoOpHttpDelegate::httpGet 18 | ( 19 | const NacosString &path, 20 | std::list &headers, 21 | std::list ¶mValues, 22 | const NacosString &_encoding, 23 | long readTimeoutMs 24 | ) NACOS_THROW(NetworkException) { 25 | HttpResult res; 26 | 27 | res = _objectConfigData->_httpCli->httpGet(path, headers, paramValues, _encoding, readTimeoutMs); 28 | return res; 29 | } 30 | 31 | HttpResult NoOpHttpDelegate::httpDelete 32 | ( 33 | const NacosString &path, 34 | std::list &headers, 35 | std::list ¶mValues, 36 | const NacosString &_encoding, 37 | long readTimeoutMs 38 | ) NACOS_THROW(NetworkException) { 39 | HttpResult res; 40 | res = _objectConfigData->_httpCli->httpDelete(path, headers, paramValues, _encoding, readTimeoutMs); 41 | return res; 42 | } 43 | 44 | HttpResult NoOpHttpDelegate::httpPost 45 | ( 46 | const NacosString &path, 47 | std::list &headers, 48 | std::list ¶mValues, 49 | const NacosString &_encoding, 50 | long readTimeoutMs 51 | ) NACOS_THROW(NetworkException) { 52 | HttpResult res; 53 | 54 | res = _objectConfigData->_httpCli->httpPost(path, headers, paramValues, _encoding, readTimeoutMs); 55 | return res; 56 | } 57 | 58 | HttpResult NoOpHttpDelegate::httpPut 59 | ( 60 | const NacosString &path, 61 | std::list &headers, 62 | std::list ¶mValues, 63 | const NacosString &_encoding, 64 | long readTimeoutMs 65 | ) NACOS_THROW(NetworkException) { 66 | 67 | HttpResult res; 68 | res = _objectConfigData->_httpCli->httpPut(path, headers, paramValues, _encoding, readTimeoutMs); 69 | return res; 70 | } 71 | 72 | }//namespace nacos 73 | -------------------------------------------------------------------------------- /src/config/ConcurrentDiskUtil.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "ConcurrentDiskUtil.h" 6 | #include "IOUtils.h" 7 | 8 | /** 9 | * get file content 10 | * 11 | * @param file file 12 | * @param charsetName charsetName 13 | * @return content 14 | * @throws IOException IOException 15 | */ 16 | 17 | namespace nacos{ 18 | NacosString 19 | ConcurrentDiskUtil::getFileContent(const NacosString &file, const NacosString &charsetName) NACOS_THROW(IOException) { 20 | if (IOUtils::checkNotExistOrNotFile(file)) { 21 | //TODO:add errorcode 22 | throw IOException(NacosException::FILE_NOT_FOUND, 23 | "checkNotExistOrNotFile failed, unable to access the file, maybe it doesn't exist."); 24 | } 25 | size_t toRead = IOUtils::getFileSize(file); 26 | FILE *fp = fopen(file.c_str(), "rb"); 27 | if (fp == NULL) { 28 | char errbuf[100]; 29 | snprintf(errbuf, sizeof(errbuf), "Failed to open file for read, errno: %d", errno); 30 | //TODO:add errorcode 31 | throw IOException(NacosException::UNABLE_TO_OPEN_FILE, errbuf); 32 | } 33 | flock(fileno(fp), LOCK_SH); 34 | char buf[toRead + 1]; 35 | fread(buf, toRead, 1, fp); 36 | buf[toRead] = '\0'; 37 | flock(fileno(fp), LOCK_UN); 38 | fclose(fp); 39 | return NacosString(buf); 40 | } 41 | 42 | /** 43 | * write file content 44 | * 45 | * @param file file 46 | * @param content content 47 | * @param charsetName charsetName 48 | * @return whether write ok 49 | * @throws IOException IOException 50 | */ 51 | bool ConcurrentDiskUtil::writeFileContent 52 | ( 53 | const NacosString &path, 54 | const NacosString &content, 55 | const NacosString &charsetName 56 | ) NACOS_THROW(IOException) { 57 | FILE *fp = fopen(path.c_str(), "wb"); 58 | if (fp == NULL) { 59 | char errbuf[100]; 60 | snprintf(errbuf, sizeof(errbuf), "Failed to open file for write, errno: %d", errno); 61 | //TODO:add errorcode 62 | throw IOException(NacosException::UNABLE_TO_OPEN_FILE, errbuf); 63 | } 64 | flock(fileno(fp), LOCK_SH); 65 | fwrite(content.c_str(), content.size(), 1, fp); 66 | flock(fileno(fp), LOCK_UN); 67 | fclose(fp); 68 | return true; 69 | } 70 | }//namespace nacos -------------------------------------------------------------------------------- /src/json/JSON.h: -------------------------------------------------------------------------------- 1 | #ifndef __JSON_H_ 2 | #define __JSON_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | #include "src/naming/beat/BeatInfo.h" 7 | #include "naming/ServiceInfo.h" 8 | #include "src/json/rapidjson/document.h" 9 | #include "src/json/rapidjson/writer.h" 10 | #include "src/json/rapidjson/stringbuffer.h" 11 | #include "naming/Instance.h" 12 | #include "src/server/NacosServerInfo.h" 13 | #include "naming/ListView.h" 14 | #include "naming/ServiceInfo2.h" 15 | #include "src/security/SecurityManager.h" 16 | #include "src/naming/subscribe/UdpNamingServiceListener.h" 17 | #include "Compatibility.h" 18 | 19 | /** 20 | * JSON 21 | * 22 | * @author Liu, Hanyu 23 | * Adapter from nacos-sdk-cpp to a json parser 24 | */ 25 | namespace nacos{ 26 | class JSON { 27 | public: 28 | static NacosString toJSONString(BeatInfo &beatInfo); 29 | 30 | static NacosString toJSONString(const std::map &mapinfo); 31 | 32 | static void Map2JSONObject(rapidjson::Document &d, rapidjson::Value &jsonOb, std::map &mapinfo); 33 | 34 | static void JSONObject2Map(std::map &mapinfo, const rapidjson::Value &jsonOb); 35 | 36 | static long getLong(const NacosString &jsonString, const NacosString &fieldname); 37 | 38 | static ServiceInfo JsonStr2ServiceInfo(const NacosString &jsonString) NACOS_THROW(NacosException); 39 | 40 | static Instance Json2Instance(const rapidjson::Value &jsonString) NACOS_THROW(NacosException); 41 | 42 | static Instance Json2Instance(const NacosString &jsonString) NACOS_THROW(NacosException); 43 | 44 | static void markRequired(const rapidjson::Document &d, const NacosString &requiredField) NACOS_THROW(NacosException); 45 | 46 | static void markRequired(const rapidjson::Value &d, const NacosString &requiredField) NACOS_THROW(NacosException); 47 | 48 | static std::list Json2NacosServerInfo(const NacosString &nacosString) NACOS_THROW(NacosException); 49 | 50 | static ServiceInfo2 Json2ServiceInfo2(const NacosString &nacosString) NACOS_THROW(NacosException); 51 | 52 | static ListView Json2ServiceList(const NacosString &nacosString) NACOS_THROW(NacosException); 53 | 54 | static AccessToken Json2AccessToken(const NacosString &nacosString) NACOS_THROW(NacosException); 55 | 56 | static PushPacket Json2PushPacket(const char *jsonString) NACOS_THROW(NacosException); 57 | }; 58 | }//namespace nacos 59 | 60 | #endif -------------------------------------------------------------------------------- /include/constant/PropertyKeyConst.h: -------------------------------------------------------------------------------- 1 | #ifndef __PROP_KEY_CONST_H_ 2 | #define __PROP_KEY_CONST_H_ 3 | 4 | #include "NacosString.h" 5 | 6 | namespace nacos{ 7 | class PropertyKeyConst { 8 | public: 9 | static const NacosString IS_USE_ENDPOINT_PARSING_RULE; 10 | 11 | static const NacosString ENDPOINT; 12 | 13 | static const NacosString ENDPOINT_PORT; 14 | 15 | static const NacosString NAMESPACE; 16 | 17 | static const NacosString ENDPOINT_QUERY_PARAMS; 18 | 19 | static const NacosString ACCESS_KEY; 20 | 21 | static const NacosString SECRET_KEY; 22 | 23 | static const NacosString APP_NAME; 24 | 25 | static const NacosString RAM_ROLE_NAME; 26 | 27 | static const NacosString SERVER_ADDR; 28 | 29 | static const NacosString CONTEXT_PATH; 30 | 31 | static const NacosString ENDPOINT_CONTEXT_PATH; 32 | 33 | static const NacosString CLUSTER_NAME; 34 | 35 | static const NacosString ENCODE; 36 | 37 | static const NacosString NAMING_LOAD_CACHE_AT_START; 38 | 39 | static const NacosString NAMING_CLIENT_BEAT_THREAD_COUNT; 40 | 41 | static const NacosString NAMING_POLLING_THREAD_COUNT; 42 | 43 | static const NacosString SRVLISTMGR_REFRESH_INTERVAL; 44 | 45 | static const NacosString SERVER_REQ_TIMEOUT; 46 | 47 | static const NacosString SUBSCRIPTION_POLL_INTERVAL; 48 | 49 | static const NacosString CONFIG_LONGPULLLING_TIMEOUT; 50 | 51 | static const NacosString HB_FAIL_WAIT_TIME; 52 | 53 | static const NacosString NACOS_SNAPSHOT_PATH; 54 | 55 | static const NacosString LOG_PATH; 56 | static const NacosString LOG_ROTATE_SIZE; 57 | static const NacosString LOG_LEVEL; 58 | 59 | static const NacosString CLIENT_NAME; 60 | static const NacosString AUTH_USERNAME; 61 | static const NacosString AUTH_PASSWORD; 62 | static const NacosString LOCAL_IP; 63 | static const NacosString UDP_RECEIVER_PORT; 64 | 65 | static const int NACOS_DEFAULT_PORT = 8848; 66 | 67 | static const NacosString INSTANCE_ID_SEQ_FILE; 68 | 69 | static const NacosString INSTANCE_ID_PREFIX; 70 | 71 | /*public static class SystemEnv { 72 | 73 | static const NacosString ALIBABA_ALIWARE_ENDPOINT_PORT = "ALIBABA_ALIWARE_ENDPOINT_PORT"; 74 | 75 | static const NacosString ALIBABA_ALIWARE_NAMESPACE = "ALIBABA_ALIWARE_NAMESPACE"; 76 | 77 | static const NacosString ALIBABA_ALIWARE_ENDPOINT_URL = "ALIBABA_ALIWARE_ENDPOINT_URL"; 78 | }*/ 79 | }; 80 | }//namespace nacos 81 | 82 | #endif -------------------------------------------------------------------------------- /src/thread/Mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUTEX_H_ 2 | #define __MUTEX_H_ 3 | 4 | #include 5 | #include 6 | #include "Tid.h" 7 | #include "src/utils/TimeUtils.h" 8 | 9 | /* 10 | * Mutex.h 11 | * Author: Liu, Hanyu 12 | * Thanks to Shuo, Chen's muduo: 13 | * https://github.com/chenshuo/muduo/blob/master/muduo/base/Mutex.h 14 | */ 15 | 16 | namespace nacos{ 17 | class Mutex { 18 | friend class Condition; 19 | 20 | private: 21 | TID_T _holder; 22 | pthread_mutex_t _mutex; 23 | public: 24 | Mutex() { pthread_mutex_init(&_mutex, NULL); }; 25 | 26 | ~Mutex() { pthread_mutex_destroy(&_mutex); }; 27 | 28 | void lock() { 29 | pthread_mutex_lock(&_mutex); 30 | assignHolder(); 31 | }; 32 | 33 | void unlock() { 34 | unassignHolder(); 35 | pthread_mutex_unlock(&_mutex); 36 | }; 37 | 38 | pthread_mutex_t *getPthreadMutex() { return &_mutex; }; 39 | 40 | void assignHolder() { _holder = gettidv1(); }; 41 | 42 | void unassignHolder() { _holder = 0; }; 43 | }; 44 | 45 | class Condition { 46 | private: 47 | Mutex &_mutex; 48 | pthread_cond_t _cond; 49 | public: 50 | Condition(Mutex &mutex) : _mutex(mutex) { pthread_cond_init(&_cond, NULL); }; 51 | 52 | ~Condition() { pthread_cond_destroy(&_cond); }; 53 | 54 | int wait() { 55 | return pthread_cond_wait(&_cond, _mutex.getPthreadMutex()); 56 | } 57 | 58 | int wait(long millis) { 59 | struct timeval now; 60 | struct timespec wakeup_time; 61 | 62 | TimeUtils::getCurrentTimeInStruct(now); 63 | now.tv_usec = now.tv_usec + millis * 1000; 64 | now.tv_sec = now.tv_sec + now.tv_usec / 1000000; 65 | now.tv_usec = now.tv_usec % 1000000; 66 | 67 | wakeup_time.tv_nsec = now.tv_usec * 1000; 68 | wakeup_time.tv_sec = now.tv_sec; 69 | //std::cout << " millis:" << millis 70 | //<< " wakeup time:sec:" << wakeup_time.tv_sec << " nsec:" << wakeup_time.tv_nsec << std::endl; 71 | 72 | return pthread_cond_timedwait(&_cond, _mutex.getPthreadMutex(), &wakeup_time); 73 | } 74 | 75 | void notify() { 76 | pthread_cond_signal(&_cond); 77 | } 78 | 79 | void notifyAll() { 80 | pthread_cond_broadcast(&_cond); 81 | } 82 | }; 83 | 84 | class LockGuard { 85 | private: 86 | Mutex &_mutex; 87 | public: 88 | LockGuard(Mutex &mutex) : _mutex(mutex) { _mutex.lock(); }; 89 | 90 | ~LockGuard() { _mutex.unlock(); }; 91 | }; 92 | }//namespace nacos 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/json/rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 17 | 18 | #include "src/json/rapidjson/stream.h" 19 | #include 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | namespace internal { 23 | 24 | //! Custom strlen() which works on different character types. 25 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 26 | \param s Null-terminated input string. 27 | \return Number of characters in the string. 28 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 29 | */ 30 | template 31 | inline SizeType StrLen(const Ch* s) { 32 | RAPIDJSON_ASSERT(s != 0); 33 | const Ch* p = s; 34 | while (*p) ++p; 35 | return SizeType(p - s); 36 | } 37 | 38 | template <> 39 | inline SizeType StrLen(const char* s) { 40 | return SizeType(std::strlen(s)); 41 | } 42 | 43 | template <> 44 | inline SizeType StrLen(const wchar_t* s) { 45 | return SizeType(std::wcslen(s)); 46 | } 47 | 48 | //! Returns number of code points in a encoded string. 49 | template 50 | bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { 51 | RAPIDJSON_ASSERT(s != 0); 52 | RAPIDJSON_ASSERT(outCount != 0); 53 | GenericStringStream is(s); 54 | const typename Encoding::Ch* end = s + length; 55 | SizeType count = 0; 56 | while (is.src_ < end) { 57 | unsigned codepoint; 58 | if (!Encoding::Decode(is, &codepoint)) 59 | return false; 60 | count++; 61 | } 62 | *outCount = count; 63 | return true; 64 | } 65 | 66 | } // namespace internal 67 | RAPIDJSON_NAMESPACE_END 68 | 69 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 70 | -------------------------------------------------------------------------------- /src/http/delegate/NacosAuthHttpDelegate.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuhanyu on 2020/12/5. 3 | // 4 | 5 | #include "NacosAuthHttpDelegate.h" 6 | #include "src/security/SecurityManager.h" 7 | 8 | using namespace std; 9 | 10 | namespace nacos { 11 | NacosString NacosAuthHttpDelegate::getEncode() const { 12 | return encoding; 13 | } 14 | 15 | NacosAuthHttpDelegate::NacosAuthHttpDelegate(ObjectConfigData *objectConfigData) { 16 | _objectConfigData = objectConfigData; 17 | } 18 | 19 | HttpResult NacosAuthHttpDelegate::httpGet 20 | ( 21 | const NacosString &path, 22 | std::list &headers, 23 | std::list ¶mValues, 24 | const NacosString &_encoding, 25 | long readTimeoutMs 26 | ) NACOS_THROW(NetworkException) { 27 | HttpResult res; 28 | _objectConfigData->_securityManager->addAccessToken2Req(paramValues); 29 | res = _objectConfigData->_httpCli->httpGet(path, headers, paramValues, _encoding, readTimeoutMs); 30 | return res; 31 | } 32 | 33 | HttpResult NacosAuthHttpDelegate::httpDelete 34 | ( 35 | const NacosString &path, 36 | std::list &headers, 37 | std::list ¶mValues, 38 | const NacosString &_encoding, 39 | long readTimeoutMs 40 | ) NACOS_THROW(NetworkException) { 41 | HttpResult res; 42 | _objectConfigData->_securityManager->addAccessToken2Req(paramValues); 43 | res = _objectConfigData->_httpCli->httpDelete(path, headers, paramValues, _encoding, readTimeoutMs); 44 | return res; 45 | } 46 | 47 | HttpResult NacosAuthHttpDelegate::httpPost 48 | ( 49 | const NacosString &path, 50 | std::list &headers, 51 | std::list ¶mValues, 52 | const NacosString &_encoding, 53 | long readTimeoutMs 54 | ) NACOS_THROW(NetworkException) { 55 | HttpResult res; 56 | _objectConfigData->_securityManager->addAccessToken2Req(paramValues); 57 | res = _objectConfigData->_httpCli->httpPost(path, headers, paramValues, _encoding, readTimeoutMs); 58 | return res; 59 | } 60 | 61 | HttpResult NacosAuthHttpDelegate::httpPut 62 | ( 63 | const NacosString &path, 64 | std::list &headers, 65 | std::list ¶mValues, 66 | const NacosString &_encoding, 67 | long readTimeoutMs 68 | ) NACOS_THROW(NetworkException) { 69 | HttpResult res; 70 | _objectConfigData->_securityManager->addAccessToken2Req(paramValues); 71 | res = _objectConfigData->_httpCli->httpPut(path, headers, paramValues, _encoding, readTimeoutMs); 72 | return res; 73 | } 74 | } -------------------------------------------------------------------------------- /src/utils/SequenceProvider.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NacosString.h" 6 | #include "NacosExceptions.h" 7 | #include "thread/AtomicInt.h" 8 | #include "src/thread/Mutex.h" 9 | #include "src/config/IOUtils.h" 10 | 11 | namespace nacos 12 | { 13 | 14 | template 15 | class SequenceProvider { 16 | private: 17 | NacosString _fileName; 18 | AtomicInt _current; 19 | Mutex _acquireMutex; 20 | T _nr_to_preserve; 21 | T _initSequence; 22 | volatile T _hwm;//high water mark 23 | 24 | void ensureWrite(int fd, T data) { 25 | size_t bytes_written = 0; 26 | while (bytes_written < sizeof(T)) { 27 | bytes_written += write(fd, (char*)&data + bytes_written, sizeof(T) - bytes_written); 28 | } 29 | } 30 | 31 | T preserve() { 32 | T current; 33 | int fd; 34 | bool newFile = false; 35 | if (IOUtils::checkNotExistOrNotFile(_fileName)) { 36 | newFile = true; 37 | } 38 | mode_t mode = S_IRUSR | S_IWUSR | S_IRWXG | S_IWGRP; 39 | fd = open(_fileName.c_str(), O_RDWR | O_CREAT, mode); 40 | if (fd <= 0) { 41 | throw new NacosException(NacosException::UNABLE_TO_OPEN_FILE, _fileName); 42 | } 43 | 44 | if (newFile) { 45 | ensureWrite(fd, _initSequence); 46 | lseek(fd, 0, SEEK_SET);//read from the beginning 47 | } 48 | 49 | size_t bytes_read = 0; 50 | while (bytes_read < sizeof(T)) 51 | { 52 | bytes_read += read(fd, (char*)¤t + bytes_read, sizeof(T) - bytes_read); 53 | } 54 | lseek(fd, 0, SEEK_SET);//write from the beginning 55 | 56 | ensureWrite(fd, current + _nr_to_preserve); 57 | close(fd); 58 | _hwm = current + _nr_to_preserve; 59 | return current; 60 | }; 61 | public: 62 | SequenceProvider(const NacosString &fileName, T initSequence, T nr_to_preserve) { 63 | _fileName = fileName; 64 | _initSequence = initSequence; 65 | _nr_to_preserve = nr_to_preserve; 66 | _current.set(preserve()); 67 | }; 68 | 69 | T next(int step = 1) { 70 | T res = _current.getAndInc(step); 71 | while (res >= _hwm) { 72 | _acquireMutex.lock(); 73 | if (res >= _hwm) { 74 | preserve(); 75 | } 76 | _acquireMutex.unlock(); 77 | } 78 | return res; 79 | }; 80 | }; 81 | 82 | } // namespace nacos 83 | -------------------------------------------------------------------------------- /test/testcase/testListenWorker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "src/log/Logger.h" 6 | #include "src/debug/DebugAssertion.h" 7 | #include "listen/Listener.h" 8 | #include "src/http/HttpDelegate.h" 9 | #include "factory/NacosFactoryFactory.h" 10 | #include "ResourceGuard.h" 11 | #include "constant/PropertyKeyConst.h" 12 | 13 | using namespace std; 14 | using namespace nacos; 15 | 16 | bool key_change_called = false; 17 | 18 | class KeyChangeListener : public Listener { 19 | private: 20 | NacosString key; 21 | public: 22 | void setKey(const NacosString &_key) { key = _key; }; 23 | 24 | NacosString getKey() const { return key; }; 25 | 26 | void receiveConfigInfo(const NacosString &configInfo) { 27 | key_change_called = true; 28 | cout << "in receiveConfigInfo: " << key << " changed to " << configInfo << endl; 29 | } 30 | }; 31 | 32 | bool testAddListener() { 33 | cout << "in function testAddListener" << endl; 34 | Properties props; 35 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 36 | ADD_AUTH_INFO(props); 37 | ADD_SPAS_INFO(props); 38 | KeyChangeListener *thelistener = new KeyChangeListener(); 39 | thelistener->setKey("k"); 40 | bool bSucc; 41 | try { 42 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 43 | ResourceGuard _guardFactory(factory); 44 | ConfigService *n = factory->CreateConfigService(); 45 | ResourceGuard _serviceFactory(n); 46 | n->removeConfig("k4", NULLSTR); 47 | n->removeConfig("k2", NULLSTR);//Known issue: this key will be monitored in next cycle(LONG_PULLING_TIME) 48 | n->removeConfig("k", NULLSTR);//so will this 49 | sleep(1); 50 | n->addListener("k4", NULLSTR, thelistener); 51 | n->addListener("k2", NULLSTR, thelistener); 52 | n->addListener("k", NULLSTR, thelistener); 53 | sleep(1); 54 | cout << "publish k" << endl; 55 | bSucc = n->publishConfig("k4", NULLSTR, "hahaha"); 56 | } 57 | catch (NacosException &e) { 58 | cout << 59 | "Failed to add listener" << endl << 60 | "Reason:" << e.what() << endl; 61 | return false; 62 | } 63 | 64 | SHOULD_BE_TRUE(key_change_called, "Notification function should be called"); 65 | SHOULD_BE_TRUE(bSucc, "Publish should succeed"); 66 | cout << "test successful" << endl; 67 | return true; 68 | } -------------------------------------------------------------------------------- /src/json/rapidjson/cursorstreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_CURSORSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | 20 | #if defined(__GNUC__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(effc++) 23 | #endif 24 | 25 | #if defined(_MSC_VER) && _MSC_VER <= 1800 26 | RAPIDJSON_DIAG_PUSH 27 | RAPIDJSON_DIAG_OFF(4702) // unreachable code 28 | RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | 34 | //! Cursor stream wrapper for counting line and column number if error exists. 35 | /*! 36 | \tparam InputStream Any stream that implements Stream Concept 37 | */ 38 | template > 39 | class CursorStreamWrapper : public GenericStreamWrapper { 40 | public: 41 | typedef typename Encoding::Ch Ch; 42 | 43 | CursorStreamWrapper(InputStream& is): 44 | GenericStreamWrapper(is), line_(1), col_(0) {} 45 | 46 | // counting line and column number 47 | Ch Take() { 48 | Ch ch = this->is_.Take(); 49 | if(ch == '\n') { 50 | line_ ++; 51 | col_ = 0; 52 | } else { 53 | col_ ++; 54 | } 55 | return ch; 56 | } 57 | 58 | //! Get the error line number, if error exists. 59 | size_t GetLine() const { return line_; } 60 | //! Get the error column number, if error exists. 61 | size_t GetColumn() const { return col_; } 62 | 63 | private: 64 | size_t line_; //!< Current Line 65 | size_t col_; //!< Current Column 66 | }; 67 | 68 | #if defined(_MSC_VER) && _MSC_VER <= 1800 69 | RAPIDJSON_DIAG_POP 70 | #endif 71 | 72 | #if defined(__GNUC__) 73 | RAPIDJSON_DIAG_POP 74 | #endif 75 | 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_ 79 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | 3 | project(nacos-sdk-cpp) 4 | 5 | #add_definitions(-DNACOS_AUTH) 6 | #add_definitions(-DNACOS_SPAS) 7 | 8 | include_directories ( 9 | . 10 | include 11 | ) 12 | 13 | aux_source_directory( src SRCS_DIRS) 14 | aux_source_directory( src/config SRCS_DIRS) 15 | aux_source_directory( src/constant SRCS_DIRS) 16 | aux_source_directory( src/crypto SRCS_DIRS) 17 | aux_source_directory( src/crypto/base64 SRCS_DIRS) 18 | aux_source_directory( src/crypto/hmac_sha1 SRCS_DIRS) 19 | aux_source_directory( src/crypto/hmac_sha1/hmac SRCS_DIRS) 20 | aux_source_directory( src/crypto/hmac_sha1/sha SRCS_DIRS) 21 | aux_source_directory( src/crypto/md5 SRCS_DIRS) 22 | aux_source_directory( src/factory SRCS_DIRS) 23 | aux_source_directory( src/http SRCS_DIRS) 24 | aux_source_directory( src/http/delegate SRCS_DIRS) 25 | aux_source_directory( src/init SRCS_DIRS) 26 | aux_source_directory( src/json SRCS_DIRS) 27 | aux_source_directory( src/json/rapidjson SRCS_DIRS) 28 | aux_source_directory( src/json/rapidjson/error SRCS_DIRS) 29 | aux_source_directory( src/json/rapidjson/internal SRCS_DIRS) 30 | aux_source_directory( src/json/rapidjson/msinttypes SRCS_DIRS) 31 | aux_source_directory( src/listen SRCS_DIRS) 32 | aux_source_directory( src/log SRCS_DIRS) 33 | aux_source_directory( src/naming SRCS_DIRS) 34 | aux_source_directory( src/naming/beat SRCS_DIRS) 35 | aux_source_directory( src/naming/cache SRCS_DIRS) 36 | aux_source_directory( src/naming/selectors SRCS_DIRS) 37 | aux_source_directory( src/naming/subscribe SRCS_DIRS) 38 | aux_source_directory( src/security SRCS_DIRS) 39 | aux_source_directory( src/server SRCS_DIRS) 40 | aux_source_directory( src/thread SRCS_DIRS) 41 | aux_source_directory( src/utils SRCS_DIRS) 42 | aux_source_directory( test SRCS_DIRS) 43 | aux_source_directory( test/testcase SRCS_DIRS) 44 | 45 | aux_source_directory(test TEST_SRCS_DIRS) 46 | aux_source_directory(test/testcase TEST_SRCS_DIRS) 47 | 48 | add_executable(nacos-cli.out ${TEST_SRCS_DIRS} ${SRCS_DIRS}) 49 | add_library(nacos-cli SHARED ${SRCS_DIRS}) 50 | add_library(nacos-cli-static STATIC ${SRCS_DIRS}) 51 | 52 | set(THREADS_PREFER_PTHREAD_FLAG ON) 53 | target_link_libraries(nacos-cli PRIVATE Threads::Threads curl z) 54 | target_link_libraries(nacos-cli-static PRIVATE Threads::Threads curl z) 55 | target_link_libraries(nacos-cli.out PRIVATE Threads::Threads curl z) 56 | find_package(Threads REQUIRED) 57 | find_package(CURL REQUIRED) 58 | find_package(ZLIB REQUIRED) 59 | 60 | install(TARGETS nacos-cli 61 | LIBRARY DESTINATION lib) 62 | 63 | install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ 64 | DESTINATION include/nacos 65 | FILES_MATCHING PATTERN "*.h*") -------------------------------------------------------------------------------- /src/json/rapidjson/ostreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_OSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_OSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. 29 | /*! 30 | The classes can be wrapped including but not limited to: 31 | 32 | - \c std::ostringstream 33 | - \c std::stringstream 34 | - \c std::wpstringstream 35 | - \c std::wstringstream 36 | - \c std::ifstream 37 | - \c std::fstream 38 | - \c std::wofstream 39 | - \c std::wfstream 40 | 41 | \tparam StreamType Class derived from \c std::basic_ostream. 42 | */ 43 | 44 | template 45 | class BasicOStreamWrapper { 46 | public: 47 | typedef typename StreamType::char_type Ch; 48 | BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} 49 | 50 | void Put(Ch c) { 51 | stream_.put(c); 52 | } 53 | 54 | void Flush() { 55 | stream_.flush(); 56 | } 57 | 58 | // Not implemented 59 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 60 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 61 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 62 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 63 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 64 | 65 | private: 66 | BasicOStreamWrapper(const BasicOStreamWrapper&); 67 | BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); 68 | 69 | StreamType& stream_; 70 | }; 71 | 72 | typedef BasicOStreamWrapper OStreamWrapper; 73 | typedef BasicOStreamWrapper WOStreamWrapper; 74 | 75 | #ifdef __clang__ 76 | RAPIDJSON_DIAG_POP 77 | #endif 78 | 79 | RAPIDJSON_NAMESPACE_END 80 | 81 | #endif // RAPIDJSON_OSTREAMWRAPPER_H_ 82 | -------------------------------------------------------------------------------- /test/testcase/testListeningKeysWithHttpPrefix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "factory/NacosFactoryFactory.h" 6 | #include "ResourceGuard.h" 7 | #include "listen/Listener.h" 8 | #include "constant/PropertyKeyConst.h" 9 | #include "src/debug/DebugAssertion.h" 10 | #include "src/log/Logger.h" 11 | 12 | using namespace std; 13 | using namespace nacos; 14 | 15 | class MyListenerHttpPrefix : public Listener { 16 | private: 17 | int num; 18 | public: 19 | MyListenerHttpPrefix(int num) { 20 | this->num = num; 21 | } 22 | 23 | void receiveConfigInfo(const NacosString &configInfo) { 24 | cout << "===================================" << endl; 25 | cout << "Watcher" << num << endl; 26 | cout << "Watched Key UPDATED:" << configInfo << endl; 27 | cout << "===================================" << endl; 28 | } 29 | }; 30 | 31 | bool testListeningKeysWithHttpPrefix() { 32 | cout << "in function testListeningKeysWithHttpPrefix" << endl; 33 | Properties props; 34 | ADD_AUTH_INFO(props); 35 | ADD_SPAS_INFO(props); 36 | props[PropertyKeyConst::SERVER_ADDR] = "HttP://127.0.0.1:8848,HtTP://localhost"; 37 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 38 | ResourceGuard _guardFactory(factory); 39 | ConfigService *n = factory->CreateConfigService(); 40 | ResourceGuard _serviceFactory(n); 41 | 42 | MyListenerHttpPrefix *theListener = new MyListenerHttpPrefix(1); 43 | MyListenerHttpPrefix *theListener2 = new MyListenerHttpPrefix(2); 44 | MyListenerHttpPrefix *theListener3 = new MyListenerHttpPrefix(3); 45 | n->addListener("dqid", NULLSTR, theListener); 46 | n->addListener("dqid", NULLSTR, theListener2); 47 | n->addListener("dqid", NULLSTR, theListener3); 48 | n->addListener("dqid1", NULLSTR, theListener3); 49 | n->addListener("dqid2", NULLSTR, theListener3); 50 | n->addListener("dqid3", NULLSTR, theListener3); 51 | 52 | for (int i = 10; i < 60; i++) { 53 | NacosString strKey = "dqid" + NacosStringOps::valueOf(i); 54 | n->addListener(strKey, NULLSTR, theListener3); 55 | } 56 | 57 | cout << "Hold for 20 secs" << endl; 58 | sleep(20); 59 | cout << "remove listener" << endl; 60 | n->removeListener("dqid", NULLSTR, theListener); 61 | 62 | cout << "Hold for 20 secs" << endl; 63 | sleep(20); 64 | cout << "remove listener2" << endl; 65 | n->removeListener("dqid", NULLSTR, theListener2); 66 | n->removeListener("dqid", NULLSTR, theListener3); 67 | cout << "test successful" << endl; 68 | 69 | return true; 70 | } -------------------------------------------------------------------------------- /src/thread/ThreadLocal.h: -------------------------------------------------------------------------------- 1 | #ifndef __THREAD_LOCAL_H_ 2 | #define __THREAD_LOCAL_H_ 3 | 4 | #include 5 | 6 | namespace nacos{ 7 | template 8 | class ThreadLocal; 9 | template 10 | struct ObjectWrapper { 11 | T wrappedObject; 12 | ThreadLocal *threadLocalObj; 13 | }; 14 | 15 | template 16 | class ThreadLocal{ 17 | private: 18 | pthread_key_t pthreadKey; 19 | T _defaultValue; 20 | static void destroyer(void *param) { 21 | ObjectWrapper *wrapper = reinterpret_cast< ObjectWrapper *>(param); 22 | wrapper->threadLocalObj->onDestroy(&wrapper->wrappedObject); 23 | delete wrapper; 24 | } 25 | 26 | ObjectWrapper *getWrapper() const { 27 | ObjectWrapper *wrapper = reinterpret_cast< ObjectWrapper *>(pthread_getspecific(pthreadKey)); 28 | return wrapper; 29 | } 30 | 31 | ObjectWrapper *createWrapper() { 32 | ObjectWrapper *wrapper = new ObjectWrapper; 33 | wrapper->threadLocalObj = this; 34 | onCreate(&wrapper->wrappedObject); 35 | pthread_setspecific(pthreadKey, reinterpret_cast(wrapper)); 36 | 37 | return wrapper; 38 | } 39 | public: 40 | ThreadLocal() { 41 | /* init the curl session */ 42 | pthread_key_create(&pthreadKey, destroyer); 43 | } 44 | 45 | ThreadLocal(T defaultValue) { 46 | _defaultValue = defaultValue; 47 | /* init the curl session */ 48 | pthread_key_create(&pthreadKey, destroyer); 49 | } 50 | 51 | void set(T value) { 52 | ObjectWrapper *wrapper = getWrapper(); 53 | if (wrapper == NULL) { 54 | wrapper = createWrapper(); 55 | } 56 | wrapper->wrappedObject = value; 57 | } 58 | 59 | T get() { 60 | ObjectWrapper *wrapper = getWrapper(); 61 | if (wrapper == NULL) { 62 | wrapper = createWrapper(); 63 | } 64 | return wrapper->wrappedObject; 65 | } 66 | 67 | virtual ~ThreadLocal() { 68 | ObjectWrapper *wrapper = getWrapper(); 69 | if (wrapper != NULL) { 70 | wrapper->threadLocalObj->onDestroy(&wrapper->wrappedObject); 71 | delete wrapper; 72 | } 73 | pthread_key_delete(pthreadKey); 74 | } 75 | 76 | virtual void onCreate(T *value) { 77 | //do nothing by default; 78 | //!!!!!shall NOT access anything other than VALUE!!!!! 79 | *value = _defaultValue; 80 | } 81 | 82 | virtual void onDestroy(T *value) { 83 | //do nothing by default; 84 | //!!!!!shall NOT access anything other than VALUE!!!!! 85 | } 86 | }; 87 | }//namespace nacos 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /include/config/ConfigService.h: -------------------------------------------------------------------------------- 1 | #ifndef __CFG_SVC_H_ 2 | #define __CFG_SVC_H_ 3 | 4 | #include "NacosExceptions.h" 5 | #include "NacosString.h" 6 | #include "listen/Listener.h" 7 | #include "Compatibility.h" 8 | namespace nacos{ 9 | class ConfigService { 10 | public: 11 | /** 12 | * Get config 13 | * 14 | * @param dataId dataId 15 | * @param group group 16 | * @param timeoutMs read timeout 17 | * @return config value 18 | * @throws NacosException NacosException 19 | */ 20 | virtual NacosString 21 | getConfig(const NacosString &dataId, const NacosString &group, long timeoutMs) NACOS_THROW(NacosException) = 0; 22 | 23 | /** 24 | * Add a listener to the configuration, after the server modified the 25 | * configuration, the client will use the incoming listener callback. 26 | * Recommended asynchronous processing, the application can implement the 27 | * getExecutor method in the ManagerListener, provide a thread pool of 28 | * execution. If provided, use the main thread callback, May block other 29 | * configurations or be blocked by other configurations. 30 | * 31 | * @param dataId dataId 32 | * @param group group 33 | * @param listener listener 34 | * @throws NacosException NacosException 35 | */ 36 | virtual void 37 | addListener(const NacosString &dataId, const NacosString &group, Listener *listener) NACOS_THROW(NacosException) = 0; 38 | 39 | /** 40 | * Publish config. 41 | * 42 | * @param dataId dataId 43 | * @param group group 44 | * @param content content 45 | * @return Whether publish 46 | * @throws NacosException NacosException 47 | */ 48 | virtual bool publishConfig(const NacosString &dataId, const NacosString &group, 49 | const NacosString &content) NACOS_THROW(NacosException) = 0; 50 | 51 | /** 52 | * Remove config 53 | * 54 | * @param dataId dataId 55 | * @param group group 56 | * @return whether remove 57 | * @throws NacosException NacosException 58 | */ 59 | virtual bool removeConfig(const NacosString &dataId, const NacosString &group) NACOS_THROW(NacosException) = 0; 60 | 61 | /** 62 | * Remove listener 63 | * 64 | * @param listener listener 65 | */ 66 | virtual void removeListener(const NacosString &dataId, const NacosString &group, Listener *listener) = 0; 67 | 68 | /** 69 | * Get server status 70 | * 71 | * @return whether health 72 | */ 73 | //virtual NacosString getServerStatus() = 0; 74 | 75 | virtual ~ConfigService() {}; 76 | }; 77 | }//namespace nacos 78 | #endif -------------------------------------------------------------------------------- /src/crypto/hmac_sha1/hmac/hmac_sha1.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file hmac_sha1.c Implements HMAC-SHA1 as of RFC 2202 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | 9 | #ifdef USE_OPENSSL 10 | #include 11 | #include 12 | #include 13 | #else 14 | 15 | #include "../sha/sha.h" 16 | 17 | #endif 18 | 19 | #include "hmac.h" 20 | 21 | 22 | /** SHA-1 Block size */ 23 | #ifndef SHA_BLOCKSIZE 24 | #define SHA_BLOCKSIZE (64) 25 | #endif 26 | 27 | 28 | /** 29 | * Function to compute the digest 30 | * 31 | * @param k Secret key 32 | * @param lk Length of the key in bytes 33 | * @param d Data 34 | * @param ld Length of data in bytes 35 | * @param out Digest output 36 | * @param t Size of digest output 37 | */ 38 | void hmac_sha1(const uint8_t *k, /* secret key */ 39 | size_t lk, /* length of the key in bytes */ 40 | const uint8_t *d, /* data */ 41 | size_t ld, /* length of data in bytes */ 42 | uint8_t *out, /* output buffer, at least "t" bytes */ 43 | size_t *t) { 44 | #ifdef USE_OPENSSL 45 | 46 | if (!HMAC(EVP_sha1(), k, (int)lk, d, ld, out, t)) { 47 | ERR_clear_error(); 48 | } 49 | #else 50 | SHA_CTX ictx, octx; 51 | uint8_t isha[SHA_DIGEST_LENGTH], osha[SHA_DIGEST_LENGTH]; 52 | uint8_t key[SHA_DIGEST_LENGTH]; 53 | uint8_t buf[SHA_BLOCKSIZE]; 54 | size_t i; 55 | 56 | if (lk > SHA_BLOCKSIZE) { 57 | SHA_CTX tctx; 58 | 59 | SHA1_Init(&tctx); 60 | SHA1_Update(&tctx, k, lk); 61 | SHA1_Final(key, &tctx); 62 | 63 | k = key; 64 | lk = SHA_DIGEST_LENGTH; 65 | } 66 | 67 | /**** Inner Digest ****/ 68 | 69 | SHA1_Init(&ictx); 70 | 71 | /* Pad the key for inner digest */ 72 | for (i = 0; i < lk; ++i) { 73 | buf[i] = k[i] ^ 0x36; 74 | } 75 | for (i = lk; i < SHA_BLOCKSIZE; ++i) { 76 | buf[i] = 0x36; 77 | } 78 | 79 | SHA1_Update(&ictx, buf, SHA_BLOCKSIZE); 80 | SHA1_Update(&ictx, d, ld); 81 | 82 | SHA1_Final(isha, &ictx); 83 | 84 | /**** Outer Digest ****/ 85 | 86 | SHA1_Init(&octx); 87 | 88 | /* Pad the key for outter digest */ 89 | 90 | for (i = 0; i < lk; ++i) { 91 | buf[i] = k[i] ^ 0x5c; 92 | } 93 | for (i = lk; i < SHA_BLOCKSIZE; ++i) { 94 | buf[i] = 0x5c; 95 | } 96 | 97 | SHA1_Update(&octx, buf, SHA_BLOCKSIZE); 98 | SHA1_Update(&octx, isha, SHA_DIGEST_LENGTH); 99 | 100 | SHA1_Final(osha, &octx); 101 | 102 | /* truncate and print the results */ 103 | *t = *t > SHA_DIGEST_LENGTH ? SHA_DIGEST_LENGTH : *t; 104 | memcpy(out, osha, *t); 105 | #endif 106 | } 107 | -------------------------------------------------------------------------------- /include/naming/ServiceInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef __SVC_INFO_H_ 2 | #define __SVC_INFO_H_ 3 | 4 | #include 5 | #include "NacosString.h" 6 | #include "naming/Instance.h" 7 | 8 | namespace nacos{ 9 | class ServiceInfo { 10 | private: 11 | //@JSONField(serialize = false) 12 | NacosString _jsonFromServer; 13 | 14 | NacosString _name; 15 | 16 | NacosString _groupName; 17 | 18 | NacosString _clusters; 19 | 20 | long _cacheMillis; 21 | 22 | //@JSONField(name = "hosts") 23 | std::list _hosts; 24 | 25 | long _lastRefTime; 26 | 27 | NacosString _checksum; 28 | 29 | volatile bool _allIPs; 30 | 31 | public: 32 | ServiceInfo(); 33 | 34 | bool isAllIPs() const; 35 | 36 | void setAllIPs(bool allIPs); 37 | 38 | explicit ServiceInfo(const NacosString &key); 39 | 40 | ServiceInfo(const NacosString &name, const NacosString &clusters); 41 | 42 | int ipCount(); 43 | 44 | bool expired() const; 45 | 46 | void setHosts(std::list &hosts); 47 | 48 | bool isValid(); 49 | 50 | NacosString getName(); 51 | 52 | void setName(const NacosString &name); 53 | 54 | NacosString getGroupName(); 55 | 56 | void setGroupName(const NacosString &groupName); 57 | 58 | void setLastRefTime(long lastRefTime); 59 | 60 | long getLastRefTime(); 61 | 62 | NacosString getClusters(); 63 | 64 | void setClusters(const NacosString &clusters); 65 | 66 | long getCacheMillis(); 67 | 68 | void setCacheMillis(long cacheMillis); 69 | 70 | std::list getHosts(); 71 | 72 | std::list *getHostsNocopy(); 73 | 74 | bool validate() const; 75 | 76 | //@JSONField(serialize = false) 77 | NacosString getJsonFromServer() const; 78 | 79 | void setJsonFromServer(const NacosString &jsonFromServer); 80 | 81 | //@JSONField(serialize = false) 82 | NacosString getKey() const; 83 | 84 | //@JSONField(serialize = false) 85 | NacosString getKeyEncoded() const; 86 | 87 | //@JSONField(serialize = false) 88 | static void fromKey(ServiceInfo &serviceInfo, const NacosString &key); 89 | 90 | //@JSONField(serialize = false) 91 | static NacosString getKey(const NacosString &name, const NacosString &clusters); 92 | 93 | //@Override 94 | NacosString toString() const; 95 | 96 | //!!BE CAREFUL!! 97 | //This function is very expensive!! call it with care! 98 | NacosString toInstanceString() const; 99 | 100 | NacosString getChecksum() const; 101 | 102 | void setChecksum(const NacosString &checksum); 103 | }; 104 | }//namespace nacos 105 | 106 | #endif -------------------------------------------------------------------------------- /test/testcase/testGetConfig.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "factory/NacosFactoryFactory.h" 3 | #include "constant/PropertyKeyConst.h" 4 | #include "src/debug/DebugAssertion.h" 5 | #include "ResourceGuard.h" 6 | #include "src/log/Logger.h" 7 | 8 | using namespace std; 9 | using namespace nacos; 10 | 11 | bool testGetConfig() { 12 | cout << "in function testGetConfig" << endl; 13 | Properties props; 14 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; 15 | ADD_AUTH_INFO(props); 16 | ADD_SPAS_INFO(props); 17 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 18 | ResourceGuard _guardFactory(factory); 19 | ConfigService *n = factory->CreateConfigService(); 20 | ResourceGuard _serviceFactory(n); 21 | NacosString ss = ""; 22 | try { 23 | ss = n->getConfig("k", NULLSTR, 1000); 24 | } 25 | catch (NacosException &e) { 26 | cout << 27 | "Request failed with curl code:" << e.errorcode() << endl << 28 | "Reason:" << e.what() << endl; 29 | return false; 30 | } 31 | cout << ss << endl; 32 | 33 | return true; 34 | } 35 | 36 | bool testGetConfigwithDefaultPort() { 37 | cout << "in function testGetConfigwithDefaultPort" << endl; 38 | Properties props; 39 | props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; 40 | ADD_AUTH_INFO(props); 41 | ADD_SPAS_INFO(props); 42 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 43 | ResourceGuard _guardFactory(factory); 44 | ConfigService *n = factory->CreateConfigService(); 45 | ResourceGuard _serviceFactory(n); 46 | NacosString ss = n->getConfig("k", NULLSTR, 1000); 47 | cout << ss << endl; 48 | 49 | return true; 50 | } 51 | 52 | bool testInvalidConfig() { 53 | cout << "in function testInvalidConfig" << endl; 54 | Properties props; 55 | ADD_AUTH_INFO(props); 56 | ADD_SPAS_INFO(props); 57 | 58 | NacosString ss; 59 | try { 60 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(props); 61 | ResourceGuard _guardFactory(factory); 62 | ConfigService *n = factory->CreateConfigService(); 63 | ResourceGuard _serviceFactory(n); 64 | ss = n->getConfig("k", NULLSTR, 1000); 65 | } 66 | catch (NacosException &e) { 67 | NacosString errmsgShouldBe = "no server address specified and the endpoint is blank"; 68 | if (errmsgShouldBe == e.what()) { 69 | return true; 70 | } else { 71 | return false; 72 | } 73 | } 74 | cout << ss << endl; 75 | 76 | return false; 77 | } -------------------------------------------------------------------------------- /src/constant/PropertyKeyConst.cpp: -------------------------------------------------------------------------------- 1 | #include "constant/PropertyKeyConst.h" 2 | 3 | namespace nacos{ 4 | const NacosString PropertyKeyConst::IS_USE_ENDPOINT_PARSING_RULE = "isUseEndpointParsingRule"; 5 | 6 | const NacosString PropertyKeyConst::ENDPOINT = "endpoint"; 7 | 8 | const NacosString PropertyKeyConst::ENDPOINT_PORT = "endpointPort"; 9 | 10 | const NacosString PropertyKeyConst::NAMESPACE = "namespace"; 11 | 12 | const NacosString PropertyKeyConst::ENDPOINT_QUERY_PARAMS = "endpointQueryParams"; 13 | 14 | const NacosString PropertyKeyConst::ACCESS_KEY = "accessKey"; 15 | 16 | const NacosString PropertyKeyConst::SECRET_KEY = "secretKey"; 17 | 18 | const NacosString PropertyKeyConst::APP_NAME = "appName"; 19 | 20 | const NacosString PropertyKeyConst::RAM_ROLE_NAME = "ramRoleName"; 21 | 22 | const NacosString PropertyKeyConst::SERVER_ADDR = "serverAddr"; 23 | 24 | const NacosString PropertyKeyConst::CONTEXT_PATH = "nacos.server.contextpath"; 25 | 26 | const NacosString PropertyKeyConst::ENDPOINT_CONTEXT_PATH = "endpointContextPath"; 27 | 28 | const NacosString PropertyKeyConst::CLUSTER_NAME = "clusterName"; 29 | 30 | const NacosString PropertyKeyConst::ENCODE = "encode"; 31 | 32 | const NacosString PropertyKeyConst::NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart"; 33 | 34 | const NacosString PropertyKeyConst::NAMING_CLIENT_BEAT_THREAD_COUNT = "namingClientBeatThreadCount"; 35 | 36 | const NacosString PropertyKeyConst::NAMING_POLLING_THREAD_COUNT = "namingPollingThreadCount"; 37 | 38 | const NacosString PropertyKeyConst::SRVLISTMGR_REFRESH_INTERVAL = "serverListMgr.refreshInterval"; 39 | 40 | const NacosString PropertyKeyConst::SERVER_REQ_TIMEOUT = "nacos.server.reqtimeout"; 41 | 42 | const NacosString PropertyKeyConst::SUBSCRIPTION_POLL_INTERVAL = "naming.poller.interval"; 43 | 44 | const NacosString PropertyKeyConst::UDP_RECEIVER_PORT = "nacos.udp.port"; 45 | 46 | const NacosString PropertyKeyConst::CONFIG_LONGPULLLING_TIMEOUT = "config.longpulling.timeout"; 47 | 48 | const NacosString PropertyKeyConst::HB_FAIL_WAIT_TIME = "naming.heartbeat.failwait"; 49 | const NacosString PropertyKeyConst::NACOS_SNAPSHOT_PATH = "nacos.snapshot.path"; 50 | 51 | const NacosString PropertyKeyConst::LOG_PATH = "nacos.log.path"; 52 | const NacosString PropertyKeyConst::LOG_ROTATE_SIZE = "nacos.log.rotateSize"; 53 | const NacosString PropertyKeyConst::LOG_LEVEL = "nacos.log.level"; 54 | 55 | const NacosString PropertyKeyConst::CLIENT_NAME = "nacos.client.name"; 56 | const NacosString PropertyKeyConst::AUTH_USERNAME = "nacos.auth.username"; 57 | const NacosString PropertyKeyConst::AUTH_PASSWORD = "nacos.auth.password"; 58 | const NacosString PropertyKeyConst::LOCAL_IP = "nacos.client.ip"; 59 | const NacosString PropertyKeyConst::INSTANCE_ID_SEQ_FILE = "nacos.instId.seq.file"; 60 | const NacosString PropertyKeyConst::INSTANCE_ID_PREFIX = "nacos.instId.prefix"; 61 | }//namespace nacos 62 | -------------------------------------------------------------------------------- /src/json/rapidjson/memorybuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYBUFFER_H_ 16 | #define RAPIDJSON_MEMORYBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "src/json/rapidjson/internal/stack.h" 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | 23 | //! Represents an in-memory output byte stream. 24 | /*! 25 | This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. 26 | 27 | It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. 28 | 29 | Differences between MemoryBuffer and StringBuffer: 30 | 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. 31 | 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. 32 | 33 | \tparam Allocator type for allocating memory buffer. 34 | \note implements Stream concept 35 | */ 36 | template 37 | struct GenericMemoryBuffer { 38 | typedef char Ch; // byte 39 | 40 | GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 41 | 42 | void Put(Ch c) { *stack_.template Push() = c; } 43 | void Flush() {} 44 | 45 | void Clear() { stack_.Clear(); } 46 | void ShrinkToFit() { stack_.ShrinkToFit(); } 47 | Ch* Push(size_t count) { return stack_.template Push(count); } 48 | void Pop(size_t count) { stack_.template Pop(count); } 49 | 50 | const Ch* GetBuffer() const { 51 | return stack_.template Bottom(); 52 | } 53 | 54 | size_t GetSize() const { return stack_.GetSize(); } 55 | 56 | static const size_t kDefaultCapacity = 256; 57 | mutable internal::Stack stack_; 58 | }; 59 | 60 | typedef GenericMemoryBuffer<> MemoryBuffer; 61 | 62 | //! Implement specialized version of PutN() with memset() for better performance. 63 | template<> 64 | inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { 65 | std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 71 | -------------------------------------------------------------------------------- /test/testcase/testHttpRequest.cpp: -------------------------------------------------------------------------------- 1 | #include "src/http/HTTPCli.h" 2 | #include "src/log/Logger.h" 3 | #include "src/debug/DebugAssertion.h" 4 | #include 5 | 6 | using namespace std; 7 | using namespace nacos; 8 | #define DEFAULT_ENCODING "UTF-8" 9 | 10 | bool testNormalHttpRequest() { 11 | cout << "in function testNormalHttpRequest" << endl; 12 | NacosString path = "http://127.0.0.1:8848/nacos/v1/ns/operator/servers"; 13 | NacosString ENCODING = DEFAULT_ENCODING; 14 | std::list headers; 15 | std::list paramValues; 16 | HTTPCli httpcli; 17 | HttpResult callres; 18 | try { 19 | callres = httpcli.httpGet(path, 20 | headers, 21 | paramValues, 22 | ENCODING, 23 | 1000); 24 | } 25 | catch (NetworkException &e) { 26 | cout << 27 | "Request failed with curl code:" << e.errorcode() << endl << 28 | "Reason:" << e.what() << endl; 29 | return false; 30 | } 31 | 32 | cout << "Http Request returned with code:" << callres.code << endl; 33 | cout << "Headers:" << endl; 34 | 35 | for (std::map::iterator it = callres.headers.begin(); 36 | it != callres.headers.end(); ++it) { 37 | cout << it->first << ":" << it->second << endl; 38 | } 39 | 40 | cout << "Content:" << callres.content << endl; 41 | return true; 42 | } 43 | 44 | bool testNoServerRequest() { 45 | cout << "in function testNoServerRequest" << endl; 46 | NacosString path = "http://127.0.0.1:9999/nacos/v1/ns/operator/servers"; 47 | NacosString ENCODING = DEFAULT_ENCODING; 48 | std::list headers; 49 | std::list paramValues; 50 | HTTPCli httpcli; 51 | HttpResult callres; 52 | try { 53 | callres = httpcli.httpGet(path, 54 | headers, 55 | paramValues, 56 | ENCODING, 57 | 1000); 58 | } 59 | catch (NetworkException &e) { 60 | //should throw a exception 61 | cout << 62 | "Request failed with curl code:" << e.errorcode() << endl << 63 | "Reason:" << e.what() << endl; 64 | return true; 65 | } 66 | 67 | cout << "Http Request returned with code:" << callres.code << endl; 68 | cout << "Headers:" << endl; 69 | 70 | for (std::map::iterator it = callres.headers.begin(); 71 | it != callres.headers.end(); ++it) { 72 | cout << it->first << ":" << it->second << endl; 73 | } 74 | 75 | cout << "Content:" << callres.content << endl; 76 | return false; 77 | } -------------------------------------------------------------------------------- /test/testcase/testDelayedThreadPool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "src/thread/DelayedThreadPool.h" 6 | #include "src/debug/DebugAssertion.h" 7 | #include "NacosExceptions.h" 8 | 9 | using namespace std; 10 | using namespace nacos; 11 | 12 | class DelayedTask : public Task { 13 | public: 14 | DelayedThreadPool *executor; 15 | uint64_t interval;// in MS 16 | uint64_t last_exec_time; 17 | DelayedTask() { 18 | last_exec_time = 0; 19 | } 20 | 21 | void run() { 22 | uint64_t now_ms = TimeUtils::getCurrentTimeInMs(); 23 | uint64_t interval_calc = 0; 24 | if (last_exec_time != 0) { 25 | interval_calc = now_ms - last_exec_time; 26 | } 27 | last_exec_time = now_ms; 28 | executor->schedule(this,now_ms + interval);//interval/1000 secs later 29 | if (executor == NULL) { 30 | throw NacosException(NacosException::INVALID_CONFIG_PARAM, "no executor"); 31 | } 32 | printf(">>>>>>>>>>>>>>>>>>Task %s triggered, time =%llu (%llu), interval = %llu\n", getTaskName().c_str(), now_ms/1000, now_ms, interval_calc); 33 | 34 | sleep(1); 35 | } 36 | }; 37 | 38 | bool testDelayedThread() { 39 | cout << "in function testDelayedThread" << endl; 40 | 41 | DelayedThreadPool dtp("testDPool", 11); 42 | dtp.start(); 43 | cout << "create tasks" << endl; 44 | 45 | DelayedTask delayedTasks[10]; 46 | 47 | uint64_t now_ms = TimeUtils::getCurrentTimeInMs(); 48 | for (size_t i = 0; i < sizeof(delayedTasks) / sizeof(DelayedTask); i++) { 49 | delayedTasks[i].executor = &dtp; 50 | delayedTasks[i].interval = (i + 1) * 1000; 51 | delayedTasks[i].setTaskName("DelayedTask-" + NacosStringOps::valueOf(i)); 52 | 53 | dtp.schedule(&delayedTasks[i], now_ms); 54 | } 55 | 56 | sleep(20); 57 | 58 | cout << "call stop()" << endl; 59 | dtp.stop(); 60 | cout << "end of test" << endl; 61 | 62 | return true; 63 | } 64 | 65 | bool testDelayedThread2() { 66 | cout << "in function testDelayedThread2 - multiple tasks triggered at the same time" << endl; 67 | 68 | DelayedThreadPool dtp("testDPool", 11); 69 | dtp.start(); 70 | cout << "create tasks" << endl; 71 | 72 | DelayedTask delayedTasks[10]; 73 | 74 | uint64_t now_ms = TimeUtils::getCurrentTimeInMs(); 75 | for (size_t i = 0; i < sizeof(delayedTasks) / sizeof(DelayedTask); i++) { 76 | delayedTasks[i].executor = &dtp; 77 | delayedTasks[i].interval = 1000; 78 | delayedTasks[i].setTaskName("DelayedTask-" + NacosStringOps::valueOf(i)); 79 | 80 | dtp.schedule(&delayedTasks[i], now_ms); 81 | } 82 | 83 | sleep(20); 84 | 85 | cout << "call stop()" << endl; 86 | dtp.stop(); 87 | cout << "end of test" << endl; 88 | 89 | return true; 90 | } 91 | -------------------------------------------------------------------------------- /src/naming/beat/BeatReactor.h: -------------------------------------------------------------------------------- 1 | #ifndef __BEAT_REACTOR_H_ 2 | #define __BEAT_REACTOR_H_ 3 | 4 | #include 5 | #include "src/naming/NamingProxy.h" 6 | #include "naming/Instance.h" 7 | #include "NacosString.h" 8 | #include "NacosExceptions.h" 9 | #include "src/thread/DelayedThreadPool.h" 10 | #include "src/thread/Thread.h" 11 | #include "src/thread/RWLock.h" 12 | #include "BeatTask.h" 13 | #include "constant/ConfigConstant.h" 14 | #include "constant/UtilAndComs.h" 15 | #include "src/factory/ObjectConfigData.h" 16 | 17 | namespace nacos{ 18 | class BeatReactor { 19 | private: 20 | ObjectConfigData *_objectConfigData; 21 | int _threadCount; 22 | RWLock _beatInfoLock; 23 | std::map _beatInfoList; 24 | volatile uint64_t _clientBeatInterval; 25 | protected: 26 | friend class BeatTask; 27 | volatile bool _stop; 28 | DelayedThreadPool *_delayedThreadPool; 29 | public: 30 | void setClientBeatInterval(uint64_t interval) { _clientBeatInterval = interval; }; 31 | 32 | uint64_t getClientBeatInterval() const { return _clientBeatInterval; }; 33 | 34 | BeatReactor(ObjectConfigData *objectConfigData, int threadCount) 35 | : _objectConfigData(objectConfigData), _beatInfoLock() { 36 | _threadCount = threadCount; 37 | _stop = true; 38 | _clientBeatInterval = 5 * 1000; 39 | _delayedThreadPool = new DelayedThreadPool("BeatReactor-Daemon", threadCount); 40 | }; 41 | 42 | BeatReactor(ObjectConfigData *objectConfigData) 43 | : _objectConfigData(objectConfigData), _beatInfoLock() { 44 | _threadCount = UtilAndComs::DEFAULT_CLIENT_BEAT_THREAD_COUNT; 45 | _stop = true; 46 | _clientBeatInterval = 5 * 1000; 47 | _delayedThreadPool = new DelayedThreadPool("BeatReactor-Daemon", _threadCount); 48 | }; 49 | 50 | ~BeatReactor() { 51 | log_debug("BeatReactor::~BeatReactor() calling stop\n"); 52 | stop(); 53 | log_debug("BeatReactor::~BeatReactor() delete threadpool\n"); 54 | delete _delayedThreadPool; 55 | _delayedThreadPool = NULL; 56 | log_debug("BeatReactor::~BeatReactor() removeAllBeatInfo()\n"); 57 | removeAllBeatInfo(); 58 | }; 59 | 60 | void start(); 61 | 62 | void stop(); 63 | 64 | void addBeatInfo(const NacosString &serviceName, BeatInfo &beatInfo); 65 | 66 | 67 | bool modifyBeatInfo(const NacosString &serviceName, BeatInfo &beatInfo); 68 | 69 | bool getBeatInfo(const NacosString &serviceName, const NacosString &ip, int port, BeatInfo &beatInfo); 70 | 71 | bool removeBeatInfo(const NacosString &serviceName, const NacosString &ip, int port); 72 | 73 | //NOTICE:Should be invoked ONLY when the working threads are ALL STOPPED 74 | void removeAllBeatInfo(); 75 | 76 | NacosString buildKey(const NacosString &serviceName, const NacosString &ip, int port); 77 | }; 78 | }//namespace nacos 79 | 80 | #endif -------------------------------------------------------------------------------- /src/json/rapidjson/memorystream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYSTREAM_H_ 16 | #define RAPIDJSON_MEMORYSTREAM_H_ 17 | 18 | #include "stream.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(unreachable-code) 23 | RAPIDJSON_DIAG_OFF(missing-noreturn) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Represents an in-memory input byte stream. 29 | /*! 30 | This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. 31 | 32 | It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. 33 | 34 | Differences between MemoryStream and StringStream: 35 | 1. StringStream has encoding but MemoryStream is a byte stream. 36 | 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. 37 | 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). 38 | \note implements Stream concept 39 | */ 40 | struct MemoryStream { 41 | typedef char Ch; // byte 42 | 43 | MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} 44 | 45 | Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } 46 | Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } 47 | size_t Tell() const { return static_cast(src_ - begin_); } 48 | 49 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 50 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 51 | void Flush() { RAPIDJSON_ASSERT(false); } 52 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 53 | 54 | // For encoding detection only. 55 | const Ch* Peek4() const { 56 | return Tell() + 4 <= size_ ? src_ : 0; 57 | } 58 | 59 | const Ch* src_; //!< Current read position. 60 | const Ch* begin_; //!< Original head of the string. 61 | const Ch* end_; //!< End of stream. 62 | size_t size_; //!< Size of the stream. 63 | }; 64 | 65 | RAPIDJSON_NAMESPACE_END 66 | 67 | #ifdef __clang__ 68 | RAPIDJSON_DIAG_POP 69 | #endif 70 | 71 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 72 | -------------------------------------------------------------------------------- /test/testcase/testEndpointWithNamingSvc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "src/naming/NamingProxy.h" 5 | #include "src/naming/NacosNamingService.h" 6 | #include "factory/NacosFactoryFactory.h" 7 | #include "ResourceGuard.h" 8 | #include "naming/Instance.h" 9 | #include "constant/ConfigConstant.h" 10 | #include "constant/UtilAndComs.h" 11 | #include "src/http/HTTPCli.h" 12 | #include "src/debug/DebugAssertion.h" 13 | #include "src/log/Logger.h" 14 | #include "NacosString.h" 15 | #include "Properties.h" 16 | #include "constant/PropertyKeyConst.h" 17 | 18 | using namespace std; 19 | using namespace nacos; 20 | 21 | bool testEndpointWithNamingProxy() { 22 | cout << "in function testEndpointWithNamingProxy" << endl; 23 | cout << "For this test, please create an endpoint on your 80 port with a file in the following path:" << endl; 24 | cout << "yourip:80/nacos/endpoint0" << endl; 25 | cout << "And the content should be a list of ip:port separated with \\n the ip:port group points at a nacos server" << endl; 26 | Properties configProps; 27 | ADD_AUTH_INFO(configProps); 28 | ADD_SPAS_INFO(configProps); 29 | configProps[PropertyKeyConst::ENDPOINT] = "127.0.0.1"; 30 | configProps[PropertyKeyConst::ENDPOINT_PORT] = "80"; 31 | configProps[PropertyKeyConst::CONTEXT_PATH] = "nacos"; 32 | configProps[PropertyKeyConst::CLUSTER_NAME] = "endpoint0"; 33 | 34 | INacosServiceFactory *factory = NacosFactoryFactory::getNacosFactory(configProps); 35 | ResourceGuard _guardFactory(factory); 36 | NamingService *namingSvc = factory->CreateNamingService(); 37 | ResourceGuard _serviceFactory(namingSvc); 38 | Instance instance; 39 | instance.clusterName = "DefaultCluster"; 40 | instance.ip = "127.0.0.1"; 41 | instance.port = 2333; 42 | instance.instanceId = "1"; 43 | instance.ephemeral = true; 44 | 45 | try { 46 | for (int i = 0; i < 5; i++) { 47 | NacosString serviceName = "TestNamingService" + NacosStringOps::valueOf(i); 48 | instance.port = 2000 + i; 49 | namingSvc->registerInstance(serviceName, instance); 50 | } 51 | } 52 | catch (NacosException &e) { 53 | cout << "encounter exception while registering service instance, raison:" << e.what() << endl; 54 | return false; 55 | } 56 | cout << "Keep the services for 30 secs..." << endl; 57 | sleep(30); 58 | cout << "Deregister the services" << endl; 59 | try { 60 | for (int i = 0; i < 5; i++) { 61 | NacosString serviceName = "TestNamingService" + NacosStringOps::valueOf(i); 62 | 63 | namingSvc->deregisterInstance(serviceName, "127.0.0.1", 2000 + i); 64 | sleep(1); 65 | } 66 | } 67 | catch (NacosException &e) { 68 | cout << "encounter exception while registering service instance, raison:" << e.what() << endl; 69 | return false; 70 | } 71 | 72 | cout << "testNamingServiceRegister finished" << endl; 73 | 74 | return true; 75 | } 76 | --------------------------------------------------------------------------------