From 70d6b452cd863d68f252677e34c9634478c58bd9 Mon Sep 17 00:00:00 2001 From: Andreas Joachim Peters Date: Tue, 11 Jun 2024 13:32:33 +0200 Subject: [PATCH] XrdCl: extend plug-inconfiguration to support defining up to 5 plug-ins in single line environment variables: export XRD_PLUGIN_1="lib=libXrdClRecorder-5.so,enable=true,url=*" export XRD_PLUGIN_2="lib=libXrdClJCache-5.so,enable=true,url=root://*" ... export XRD_PLUGIN_5="..." --- src/XrdCl/XrdClDefaultEnv.cc | 6 ++++ src/XrdCl/XrdClPlugInManager.cc | 54 +++++++++++++++++++++++++++++++-- src/XrdCl/XrdClPlugInManager.hh | 5 +++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/XrdCl/XrdClDefaultEnv.cc b/src/XrdCl/XrdClDefaultEnv.cc index 2b1878002cf..94bc99126bb 100644 --- a/src/XrdCl/XrdClDefaultEnv.cc +++ b/src/XrdCl/XrdClDefaultEnv.cc @@ -311,6 +311,12 @@ namespace XrdCl REGISTER_VAR_STR( varsStr, "ClientMonitorParam", DefaultClientMonitorParam ); REGISTER_VAR_STR( varsStr, "NetworkStack", DefaultNetworkStack ); REGISTER_VAR_STR( varsStr, "PlugIn", DefaultPlugIn ); + REGISTER_VAR_STR( varsStr, "PlugIn_1", DefaultPlugIn ); + REGISTER_VAR_STR( varsStr, "PlugIn_2", DefaultPlugIn ); + REGISTER_VAR_STR( varsStr, "PlugIn_3", DefaultPlugIn ); + REGISTER_VAR_STR( varsStr, "PlugIn_4", DefaultPlugIn ); + REGISTER_VAR_STR( varsStr, "PlugIn_5", DefaultPlugIn ); + REGISTER_VAR_STR( varsStr, "PlugIn_6", DefaultPlugIn ); REGISTER_VAR_STR( varsStr, "PlugInConfDir", DefaultPlugInConfDir ); REGISTER_VAR_STR( varsStr, "ReadRecovery", DefaultReadRecovery ); REGISTER_VAR_STR( varsStr, "WriteRecovery", DefaultWriteRecovery ); diff --git a/src/XrdCl/XrdClPlugInManager.cc b/src/XrdCl/XrdClPlugInManager.cc index 3fdaf149630..6c9a0bd4194 100644 --- a/src/XrdCl/XrdClPlugInManager.cc +++ b/src/XrdCl/XrdClPlugInManager.cc @@ -243,6 +243,42 @@ namespace XrdCl if( !customPlugIns.empty() ) ProcessConfigDir( customPlugIns ); } + + //-------------------------------------------------------------------------- + // Support for loading plugins accoring to environment setting + // First plugin XRD_PLUGIN_1 ="key1=val1,key2=val2,key3=val3" + // Second plugin XRD_PLUGIN_2="key1=val1,key2=val2,key3=val3" + // ... + // Fifth plugin XRD_PLUGIN_5="key1=val1,key2=val2,key3=val3" + //-------------------------------------------------------------------------- + std::string envprefix = "XRD_PLUGIN"; + const std::array ENVS = {"_1", "_2", "_3", "_4", "_5"}; + + for (const auto& penv : ENVS) { + std::string pluginenv = envprefix + penv; + std::string envString; + if ( env->GetString(pluginenv, envString) && envString.length() ) { + std::map envMap; + std::stringstream ss(envString); + std::string item; + + // Split the environment variable string by commas + while (std::getline(ss, item, ',')) { + Log *log = DefaultEnv::GetLog(); + std::stringstream itemStream(item); + std::string key, value; + + // Split each key-value pair by the equal sign + if (std::getline(itemStream, key, '=') && std::getline(itemStream, value)) { + envMap[key] = value; + log->Debug( PlugInMgrMsg, "Processing plug-in definitions from environment %s->%s...", + key.c_str(), value.c_str()); + } + } + std::string origin = std::string("env{") + pluginenv + std::string("}"); + ProcessConfig(envMap,origin); + } + } } //---------------------------------------------------------------------------- @@ -298,13 +334,27 @@ namespace XrdCl return; } + return this->ProcessConfig(config, confFile); + } + + //---------------------------------------------------------------------------- + // Process a plug-in config map and load the plug-in if possible + //---------------------------------------------------------------------------- + + void PlugInManager::ProcessConfig(std::map& config, const std::string& confOrigin) + { + Log *log = DefaultEnv::GetLog(); + + for (auto i:config) { + log->Debug( PlugInMgrMsg, "'%s'=>'%s'", i.first.c_str(), i.second.c_str()); + } const char *keys[] = { "url", "lib", "enable", 0 }; for( int i = 0; keys[i]; ++i ) { if( config.find( keys[i] ) == config.end() ) { log->Debug( PlugInMgrMsg, "Unable to find '%s' key in the config file " - "%s, ignoring this config", keys[i], confFile.c_str() ); + "%s, ignoring this config", keys[i], confOrigin.c_str() ); return; } } @@ -317,7 +367,7 @@ namespace XrdCl std::string enable = config["enable"]; log->Dump( PlugInMgrMsg, "Settings from '%s': url='%s', lib='%s', " - "enable='%s'", confFile.c_str(), url.c_str(), lib.c_str(), + "enable='%s'", confOrigin.c_str(), url.c_str(), lib.c_str(), enable.c_str() ); std::pair pg; diff --git a/src/XrdCl/XrdClPlugInManager.hh b/src/XrdCl/XrdClPlugInManager.hh index a7a5439b118..54356f5db2c 100644 --- a/src/XrdCl/XrdClPlugInManager.hh +++ b/src/XrdCl/XrdClPlugInManager.hh @@ -144,6 +144,11 @@ namespace XrdCl //------------------------------------------------------------------------ void ProcessPlugInConfig( const std::string &confFile ); + //------------------------------------------------------------------------ + //! Process a plug-in config file and load the plug-in if possible + //------------------------------------------------------------------------ + void ProcessConfig(std::map& config, const std::string& configOrigin); + //------------------------------------------------------------------------ //! Load the plug-in and create the factory //------------------------------------------------------------------------