From dfc9f8de099fb90b3c4e46f3753267b76af37b39 Mon Sep 17 00:00:00 2001 From: Terrence Asselin Date: Thu, 6 Feb 2025 10:16:32 -0600 Subject: [PATCH 1/2] HPCC-33292 Common-up code for creating roxie connection map - Move common code in shared functions in SMCLib. - Rename initBareMetalRoxieTargets implementation in ws_ecl to indicate it has behavior specific to ws_ecl. The major differences that couldn't be commoned up are that it maps roxie targets by logical name and alias instead of by physical name, and it may use VIPs or a daliServer as endpoints. - Use applicable shared function from SMCLib in ws_ecl. - Note that this will change ws_ecl behavior in a small but positive way. It now prefers a secure roxie server endpoint over a non-secure. - Update CMake files to include and link SMCLib in ws_ecl. - Remove SDS_LOCK_TIMEOUT define from ws_ecl_service.cpp that wasn't used and conflicted with another newly-included definition. Signed-off-by: Terrence Asselin --- esp/services/ws_ecl/CMakeLists.txt | 3 ++ esp/services/ws_ecl/ws_ecl_service.cpp | 52 +++--------------------- esp/smc/SMCLib/TpWrapper.cpp | 56 ++++++++++++++------------ esp/smc/SMCLib/TpWrapper.hpp | 10 +++++ 4 files changed, 49 insertions(+), 72 deletions(-) diff --git a/esp/services/ws_ecl/CMakeLists.txt b/esp/services/ws_ecl/CMakeLists.txt index 3cbe3f4780a..7e354343025 100644 --- a/esp/services/ws_ecl/CMakeLists.txt +++ b/esp/services/ws_ecl/CMakeLists.txt @@ -52,6 +52,8 @@ include_directories ( ./../../../common/fileview2 ./../../../dali/base ${HPCC_SOURCE_DIR}/common/thorhelper + ${HPCC_SOURCE_DIR}/esp/smc/SMCLib + ${HPCC_SOURCE_DIR}/dali/sasha ) ADD_DEFINITIONS( -D_USRDLL ) @@ -77,6 +79,7 @@ target_link_libraries ( ws_ecl hql fileview2 xmllib + SMCLib ${COMMON_ESP_SERVICE_LIBS} ) diff --git a/esp/services/ws_ecl/ws_ecl_service.cpp b/esp/services/ws_ecl/ws_ecl_service.cpp index c2a963fc8a3..cb914606c4f 100644 --- a/esp/services/ws_ecl/ws_ecl_service.cpp +++ b/esp/services/ws_ecl/ws_ecl_service.cpp @@ -13,7 +13,8 @@ #include "jsonhelpers.hpp" #include "securesocket.hpp" -#define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short +#include "TpWrapper.hpp" + #define WSECL_ACCESS "WsEclAccess" static const char* WSECL_ACCESS_DENIED = "WsEcl access permission denied."; @@ -178,30 +179,6 @@ static void escapeSingleQuote(StringBuffer& src, StringBuffer& escaped) } } -static void appendServerAddress(StringBuffer &s, IPropertyTree &env, IPropertyTree &server, const char *daliAddress, const char *farmerPort) -{ - //just in case, for backward compatability with old environment.xml files, allow server rather than farmer to specify port - const char *port = server.queryProp("@port"); - if (!port) - port = farmerPort; - if (port && streq(port, "0")) //0 == roxie listening on queue rather than port - return; - - const char *netAddress = server.queryProp("@netAddress"); - if (!netAddress && server.hasProp("@computer")) - { - VStringBuffer xpath("Hardware/Computer[@name='%s']/@netAddress", server.queryProp("@computer")); - netAddress = env.queryProp(xpath.str()); - } - if ((!netAddress || *netAddress=='.') && daliAddress && *daliAddress) - netAddress = daliAddress; - if (!netAddress || !*netAddress) - return; - if (s.length()) - s.append('|'); - s.append(netAddress).append(':').append(port ? port : "9876"); -} - class WsEclSocketFactory : public CSmartSocketFactory { public: @@ -234,7 +211,7 @@ void initContainerRoxieTargets(MapStringToMyClass &connMap) } #ifndef _CONTAINERIZED -void initBareMetalRoxieTargets(MapStringToMyClass &connMap, IPropertyTree *serviceTree, const char *daliAddress) +void initWsEclBareMetalRoxieTargets(MapStringToMyClass &connMap, IPropertyTree *serviceTree, const char *daliAddress) { IPropertyTree *vips = serviceTree->queryPropTree("VIPS"); Owned roxieTargets = getTargetClusters("RoxieCluster", NULL); @@ -283,29 +260,10 @@ void initBareMetalRoxieTargets(MapStringToMyClass &connMap, } else { - const char *farmerPort = nullptr; VStringBuffer xpath("Software/RoxieCluster[@name='%s'][1]", process.str()); IPropertyTree *roxieCluster = pRoot->queryPropTree(xpath.str()); if (roxieCluster) - { - //port and TLS config come from farmer, node addresses come from server - Owned farmers = roxieCluster->getElements("RoxieFarmProcess"); - ForEach(*farmers) - { - IPropertyTree &farmer = farmers->query(); - const char *port = farmer.queryProp("@port"); - if (!port || streq(port, "0")) - continue; - farmerPort = port; - const char *protocol = farmer.queryProp("@protocol"); - if (protocol && streq(protocol, "ssl")) - tlsConfig.setown(createSecureSocketConfig(farmer.queryProp("@certificateFileName"), farmer.queryProp("@privateKeyFileName"), nullptr, true)); - break; //use the first one without port==0 - } - Owned servers = roxieCluster->getElements("RoxieServerProcess"); - ForEach(*servers) - appendServerAddress(list, *pRoot, servers->query(), daliAddress, farmerPort); - } + getAddressesAndTlsConfigForRoxieProcess(*pRoot, *roxieCluster, list, tlsConfig, daliAddress); } if (list.length()) { @@ -359,7 +317,7 @@ bool CWsEclService::init(const char * name, const char * type, IPropertyTree * c #ifdef _CONTAINERIZED initContainerRoxieTargets(connMap); #else - initBareMetalRoxieTargets(connMap, serviceTree, daliAddress.str()); + initWsEclBareMetalRoxieTargets(connMap, serviceTree, daliAddress.str()); #endif translator = new wsEclTypeTranslator(); diff --git a/esp/smc/SMCLib/TpWrapper.cpp b/esp/smc/SMCLib/TpWrapper.cpp index 05ab0c82c34..e72bfc29e95 100644 --- a/esp/smc/SMCLib/TpWrapper.cpp +++ b/esp/smc/SMCLib/TpWrapper.cpp @@ -2093,7 +2093,7 @@ extern TPWRAPPER_API void initContainerRoxieTargets(MapStringToMyClass tlsConfig = createPTree("none"); + Owned tlsConfig; + getAddressesAndTlsConfigForRoxieProcess(*envRoot, roxieCluster, addressList, tlsConfig, nullptr); - Owned roxieFarms = roxieCluster.getElements("RoxieFarmProcess"); - ForEach(*roxieFarms) + Owned sf = tlsConfig.get() != nullptr ? createSecureSmartSocketFactory(addressList, tlsConfig) : createSmartSocketFactory(addressList); + connMap.setValue(name, sf.get()); + } +} + +extern TPWRAPPER_API void getAddressesAndTlsConfigForRoxieProcess(IPropertyTree& env, IPropertyTree& roxieCluster, StringBuffer& addrList, Owned & tlsConfig, const char* daliAddress) +{ + StringBuffer preferredPort; + Owned roxieFarms = roxieCluster.getElements("RoxieFarmProcess"); + ForEach(*roxieFarms) + { + IPropertyTree& farm = roxieFarms->query(); + const char* farmPort = farm.queryProp("@port"); + if (!isEmptyString(farmPort) && !streq(farmPort, "0")) { - IPropertyTree& farm = roxieFarms->query(); - const char* farmPort = farm.queryProp("@port"); - if (!isEmptyString(farmPort) && !streq(farmPort, "0")) + const char *protocol = farm.queryProp("@protocol"); + if (!isEmptyString(protocol) && strieq(protocol, "ssl")) { - const char *protocol = farm.queryProp("@protocol"); - if (!isEmptyString(protocol) && strieq(protocol, "ssl")) - { - port.set(farmPort); - tlsConfig.setown(createSecureSocketConfig(farm.queryProp("@certificateFileName"), farm.queryProp("@privateKeyFileName"), nullptr, true)); - break; - } - else if (isEmptyString(port.str())) - { - port.set(farmPort); - } + preferredPort.set(farmPort); + tlsConfig.setown(createSecureSocketConfig(farm.queryProp("@certificateFileName"), farm.queryProp("@privateKeyFileName"), nullptr, true)); + break; + } + else if (isEmptyString(preferredPort.str())) + { + preferredPort.set(farmPort); } } - - Owned roxieServers = roxieCluster.getElements("RoxieServerProcess"); - ForEach(*roxieServers) - appendServerAddress(addressList, *envRoot, roxieServers->query(), port.str()); - - Owned sf = streq(tlsConfig->queryName(), "ssl") ? createSecureSmartSocketFactory(addressList, tlsConfig) : createSmartSocketFactory(addressList); - connMap.setValue(name, sf.get()); } + Owned roxieServers = roxieCluster.getElements("RoxieServerProcess"); + ForEach(*roxieServers) + appendServerAddress(addrList, env, roxieServers->query(), preferredPort.str(), daliAddress); } extern TPWRAPPER_API void getRoxieTargetsSupportingPublishedQueries(StringArray& names) diff --git a/esp/smc/SMCLib/TpWrapper.hpp b/esp/smc/SMCLib/TpWrapper.hpp index e239a920b4d..03f55544509 100644 --- a/esp/smc/SMCLib/TpWrapper.hpp +++ b/esp/smc/SMCLib/TpWrapper.hpp @@ -227,6 +227,16 @@ extern TPWRAPPER_API unsigned getContainerWUClusterInfo(CConstWUClusterInfoArray extern TPWRAPPER_API unsigned getWUClusterInfo(CConstWUClusterInfoArray& clusters); extern TPWRAPPER_API IConstWUClusterInfo* getWUClusterInfoByName(const char* clustName); +/** + * Get pipe-delimited list of roxie server addresses and TLS config from environment configuration for the roxie process named `process`. + * @param env environment configuration + * @param process roxie process name + * @param addrList pipe-delimited list of roxie server addresses + * @param tlsConfig TLS configuration + * @param daliAddress optional dali address to use for ws_ecl service if `@netAddress` not found in `server` configuration + * @return void + */ +extern TPWRAPPER_API void getAddressesAndTlsConfigForRoxieProcess(IPropertyTree& env, IPropertyTree& roxieCluster, StringBuffer& addrList, Owned & tlsConfig, const char* daliAddress); extern TPWRAPPER_API void initContainerRoxieTargets(MapStringToMyClass& connMap); extern TPWRAPPER_API void initBareMetalRoxieTargets(MapStringToMyClass& connMap); extern TPWRAPPER_API unsigned getThorClusterNames(StringArray& targetNames, StringArray& queueNames); From a665429e85d6d14f5246adaab449a2bd80577b6b Mon Sep 17 00:00:00 2001 From: Terrence Asselin Date: Fri, 14 Feb 2025 09:54:20 -0600 Subject: [PATCH 2/2] HPCC-33292 Correct comments per code review Signed-off-by: Terrence Asselin --- esp/smc/SMCLib/TpWrapper.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp/smc/SMCLib/TpWrapper.hpp b/esp/smc/SMCLib/TpWrapper.hpp index 03f55544509..6748a3991db 100644 --- a/esp/smc/SMCLib/TpWrapper.hpp +++ b/esp/smc/SMCLib/TpWrapper.hpp @@ -228,9 +228,9 @@ extern TPWRAPPER_API unsigned getWUClusterInfo(CConstWUClusterInfoArray& cluster extern TPWRAPPER_API IConstWUClusterInfo* getWUClusterInfoByName(const char* clustName); /** - * Get pipe-delimited list of roxie server addresses and TLS config from environment configuration for the roxie process named `process`. + * Get pipe-delimited list of roxie server addresses and TLS config from roxie process `roxieCluster` configuration. * @param env environment configuration - * @param process roxie process name + * @param roxieCluster roxie process configuration to get addresses and TLS config from * @param addrList pipe-delimited list of roxie server addresses * @param tlsConfig TLS configuration * @param daliAddress optional dali address to use for ws_ecl service if `@netAddress` not found in `server` configuration