From 9cf00eb35e4b66639ca46963f7ef3b7d028e3b19 Mon Sep 17 00:00:00 2001 From: HaseenaSainul Date: Thu, 26 Sep 2024 08:56:50 -0400 Subject: [PATCH] Update based on comments --- Source/Thunder/IRemoteInstantiation.h | 3 +- Source/Thunder/PluginServer.h | 82 +++++++++++++++++++-------- Source/ThunderPlugin/Process.cpp | 41 +++++--------- Source/com/Communicator.h | 27 +++++++-- Source/com/Ids.h | 1 + Source/plugins/Configuration.h | 46 ++++++++++++++- Source/plugins/IShell.h | 3 - Source/plugins/Shell.cpp | 4 +- 8 files changed, 141 insertions(+), 66 deletions(-) diff --git a/Source/Thunder/IRemoteInstantiation.h b/Source/Thunder/IRemoteInstantiation.h index 988ab4e58..169bb4a0a 100644 --- a/Source/Thunder/IRemoteInstantiation.h +++ b/Source/Thunder/IRemoteInstantiation.h @@ -27,6 +27,7 @@ namespace PluginHost { struct IRemoteInstantiation : virtual public Core::IUnknown { enum { ID = RPC::IDS::ID_REMOTE_INSTANTIATION }; + using IEnvironmentIterator = RPC::IIteratorType; ~IRemoteInstantiation() override = default; @@ -57,7 +58,7 @@ namespace PluginHost { const uint8_t threads, const int8_t priority, const string configuration, - const std::vector& environments) = 0; + IEnvironmentIterator* const& environments) = 0; }; } } diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index 5e6a29049..85dc481a3 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -377,6 +377,8 @@ namespace PluginHost { DYNAMIC }; + using Services = std::unordered_map; + private: using BaseClass = PluginHost::Service; using Jobs = Core::ThrottleQueueType, ServiceMap&>; @@ -1277,37 +1279,33 @@ namespace PluginHost { string Substitute(const string& input) const override { return (_administrator.Configuration().Substitute(input, PluginHost::Service::Configuration())); } - std::vector SubstituteList(const string& envs) const override { - - std::vector environmentList;; - Plugin::Config::EnvironmentList environments; - environments.FromString(envs); - if (environments.IsSet() == true) { - Core::JSON::ArrayType::Iterator index(environments.Elements()); - while (index.Next() == true) { - if ((index.Current().Key.IsSet() == true) && (index.Current().Value.IsSet() == true)) { - index.Current().Value = Substitute(index.Current().Value.Value()); - string env = index.Current().Key.Value() + Plugin::Config::EnvFieldSeparator + - index.Current().Value.Value() + Plugin::Config::EnvFieldSeparator + - ((index.Current().Override.Value() == true) ? "1" : "0"); - environmentList.push_back(env); - } else { - SYSLOG(Logging::Startup, (_T("Failure in Substituting Value of Key:Value:[%s]:[%s]\n"), index.Current().Key.Value().c_str(), index.Current().Value.Value().c_str())); - } - } - } - return environmentList; - } Core::hresult Metadata(string& info /* @out */) const override { Metadata::Service result; GetMetadata(result); result.ToString(info); return (Core::ERROR_NONE); } + std::vector SubstituteList(const std::vector& environments) const { + std::vector environmentList; + for (auto& environment : environments) { + if ((environment.key.empty() != true) && (environment.value.empty() != true)) { + RPC::Object::Environment env; + env.value = Substitute(environment.value); + env.key = environment.key; + env.overriding = environment.overriding; + environmentList.push_back(environment); + } else { + SYSLOG(Logging::Startup, (_T("Failure in Substituting Value of Key:Value:[%s]:[%s]\n"), environment.key.c_str(), environment.value.c_str())); + } + } + return environmentList; + } void* Instantiate(const RPC::Object& object, const uint32_t waitTime, uint32_t& sessionId) override { ASSERT(_connection == nullptr); + const_cast(object).Environments(SubstituteList(object.Environments())); + void* result(_administrator.Instantiate(object, waitTime, sessionId, DataPath(), PersistentPath(), VolatilePath(), _administrator.Configuration().LinkerPluginPaths())); if (result != nullptr) { @@ -1536,7 +1534,7 @@ namespace PluginHost { SystemRootPath(), PluginHost::Service::Configuration().Root.RemoteAddress.Value(), PluginHost::Service::Configuration().Root.Configuration.Value(), - SubstituteList(environments)); + Plugin::Config::Environment::List(PluginHost::Service::Configuration().Root.Environments)); newIF = reinterpret_cast(Instantiate(definition, _administrator.Configuration().OutOfProcessWaitTime(), pid)); if (newIF == nullptr) { @@ -2031,6 +2029,10 @@ namespace PluginHost { if (instantiation == nullptr) { result = Core::ERROR_ILLEGAL_STATE; } else { + + using Iterator = IRemoteInstantiation::IEnvironmentIterator; + Iterator* environment = Core::Service>::Create(_object.Environments()); + result = instantiation->Instantiate( RPC::Communicator::RemoteConnection::Id(), _object.Locator(), @@ -2044,7 +2046,7 @@ namespace PluginHost { _object.Threads(), _object.Priority(), _object.Configuration(), - _object.Environments()); + environment); instantiation->Release(); } @@ -2425,7 +2427,7 @@ namespace PluginHost { const uint8_t threads, const int8_t priority, const string configuration, - const std::vector& environments) override + IRemoteInstantiation::IEnvironmentIterator* const& environments) override { string persistentPath(_comms.PersistentPath()); string dataPath(_comms.DataPath()); @@ -2437,9 +2439,17 @@ namespace PluginHost { volatilePath += callsign + '/'; } + std::vector _environmentList; + if (environments != nullptr) { + RPC::Object::Environment environment; + while (environments->Next(environment) == true) { + _environmentList.push_back(environment); + } + } + uint32_t id; RPC::Config config(_connector, _comms.Application(), persistentPath, _comms.SystemPath(), dataPath, volatilePath, _comms.AppPath(), _comms.ProxyStubPath(), _comms.PostMortemPath(), _comms.LinkerPaths()); - RPC::Object instance(libraryName, className, callsign, interfaceId, version, user, group, threads, priority, RPC::Object::HostType::LOCAL, systemRootPath, _T(""), configuration, environments); + RPC::Object instance(libraryName, className, callsign, interfaceId, version, user, group, threads, priority, RPC::Object::HostType::LOCAL, systemRootPath, _T(""), configuration, _environmentList); RPC::Communicator::Process process(requestId, config, instance); @@ -2450,6 +2460,17 @@ namespace PluginHost { INTERFACE_ENTRY(IRemoteInstantiation) END_INTERFACE_MAP + private: + std::vector SubstituteList(const string& callsign, const std::vector& environments) const + { + std::vector substitutedList; + Core::ProxyType service = _parent.GetService(callsign); + if (service.IsValid() == true) { + substitutedList = service->SubstituteList(environments); + } + return substitutedList; + } + private: mutable uint32_t _refCount; ServiceMap& _parent; @@ -3090,6 +3111,17 @@ namespace PluginHost { _adminLock.Unlock(); } + inline Core::ProxyType GetService(const string& callsign) + { + Core::ProxyType service; + for (std::pair>& entry : _services) { + if (entry.first == callsign) { + service = entry.second; + break; + } + } + return service; + } inline Iterator Services() { Shells workingList; diff --git a/Source/ThunderPlugin/Process.cpp b/Source/ThunderPlugin/Process.cpp index ad1ad094a..e7cab38c8 100644 --- a/Source/ThunderPlugin/Process.cpp +++ b/Source/ThunderPlugin/Process.cpp @@ -159,7 +159,7 @@ POP_WARNING() class ConsoleOptions : public Core::Options { public: ConsoleOptions(int argumentCount, TCHAR* arguments[]) - : Core::Options(argumentCount, arguments, _T("h:l:c:C:r:p:s:d:a:m:i:u:g:t:e:x:V:v:P:S:f:")) + : Core::Options(argumentCount, arguments, _T("h:l:c:C:r:p:s:d:a:m:i:u:g:t:e:E:x:V:v:P:S:f:")) , Locator(nullptr) , ClassName(nullptr) , Callsign(nullptr) @@ -202,7 +202,7 @@ POP_WARNING() string ProxyStubPath; string PostMortemPath; string SystemRootPath; - std::vector Environments; + std::vector Environments; const TCHAR* User; const TCHAR* Group; uint8_t Threads; @@ -252,8 +252,12 @@ POP_WARNING() SystemRootPath = Core::Directory::Normalize(Strip(argument)); break; case 'e': - Environments.push_back(Strip(argument)); + case 'E': { + Environments.push_back(Plugin::Config::Environment::Info(Strip(argument), + ((option == 'E') ? RPC::Object::Environment::Scope::GLOBAL : + RPC::Object::Environment::Scope::LOCAL))); break; + } case 'v': VolatilePath = Core::Directory::Normalize(Strip(argument)); break; @@ -592,7 +596,8 @@ int main(int argc, char** argv) printf(" [-d ]\n"); printf(" [-v ]\n"); printf(" [-f ...\n"); - printf(" [-e ...]\n\n"); + printf(" [-e/-E ...]\n"); + printf(" e: means set as local scope, E: means set as global scope\n"); printf(" [-a ]\n"); printf(" [-m ]\n"); printf(" [-P ]\n\n"); @@ -669,28 +674,12 @@ int main(int argc, char** argv) Core::ProcessCurrent().User(string(options.User)); } - for (const string& env : options.Environments) { - size_t start = env.find_first_of(Plugin::Config::EnvFieldSeparator); - if ((start != string::npos) && (start < env.length())) { - size_t end = env.find_last_of(Plugin::Config::EnvFieldSeparator); - if ((end != string::npos) && (start != end)) { - string key = env.substr(0, start); - string value = env.substr(start + 1, end - (start + 1)); - string overrideStr = env.substr(end + 1); - - bool toOverride = ((overrideStr.size() == 1) && (overrideStr == "1")) ? true: false; - - if ((key.empty() != true) && (value.empty() != true)) { - uint32_t status = Core::SystemInfo::SetEnvironment(key, value.c_str(), toOverride); - if (status != true) { - SYSLOG(Logging::Startup, (_T("Failure in setting Key:Value:[%s]:[%s]\n"), key.c_str(), value.c_str())); - } - } else { - SYSLOG(Logging::Startup, (_T("Environment key:value fromat is invalid :[%s]:[%s]\n"), key.c_str(), value.c_str())); - } - } else { - SYSLOG(Logging::Startup, (_T("Invalid Enviroment value :[%s]\n"), env.c_str())); - } + for (const auto& info : options.Environments) { + if ((info.key.empty() != true) && (info.value.empty() != true)) { + uint32_t status = Core::SystemInfo::SetEnvironment(info.key, info.value.c_str(), ((info.overriding == RPC::Object::Environment::Scope::GLOBAL) ? true : false)); + if (status != true) { + SYSLOG(Logging::Startup, (_T("Failure in setting Key:Value:[%s]:[%s]\n"), info.key.c_str(), info.value.c_str())); + } } } diff --git a/Source/com/Communicator.h b/Source/com/Communicator.h index bedaf6731..febde29ef 100644 --- a/Source/com/Communicator.h +++ b/Source/com/Communicator.h @@ -45,12 +45,23 @@ namespace RPC { class EXTERNAL Object { public: + static constexpr const TCHAR EnvironmentSeparator = _T(';'); enum class HostType { LOCAL, DISTRIBUTED, CONTAINER }; + struct Environment { + enum class Scope { + LOCAL, + GLOBAL + }; + string key; + string value; + Scope overriding; + }; + Object() : _locator() , _className() @@ -115,7 +126,7 @@ namespace RPC { const string& systemRootPath, const string& remoteAddress, const string& configuration, - const std::vector& environments) + const std::vector& environments) : _locator(locator) , _className(className) , _callsign(callsign) @@ -235,10 +246,13 @@ namespace RPC { { return (_configuration); } - inline const std::vector& Environments() const + inline const std::vector& Environments() const { return (_environments); } + inline void Environments(const std::vector& environments) { + _environments = environments; + } private: string _locator; @@ -254,7 +268,7 @@ namespace RPC { string _systemRootPath; string _remoteAddress; string _configuration; - std::vector _environments; + std::vector _environments; }; class EXTERNAL Config { @@ -527,8 +541,11 @@ namespace RPC { if (instance.Threads() > 1) { _options.Add(_T("-t")).Add(Core::NumberType(instance.Threads()).Text()); } - for (auto const& env : instance.Environments()) { - _options.Add(_T("-e")).Add('"' + env + '"'); + for (auto const& environment : instance.Environments()) { + string env = environment.key + RPC::Object::EnvironmentSeparator + + "\"" + environment.value + "\""; + string option = (environment.overriding == RPC::Object::Environment::Scope::GLOBAL) ? "E" : "e"; + _options.Add(_T(option)).Add('"' + env + '"'); } _priority = instance.Priority(); } diff --git a/Source/com/Ids.h b/Source/com/Ids.h index 9c387bdbb..6c1a3b07d 100644 --- a/Source/com/Ids.h +++ b/Source/com/Ids.h @@ -89,6 +89,7 @@ namespace RPC { ID_SUBSYSTEM_DECRYPTION = (ID_OFFSET_INTERNAL + 0x003E), ID_REMOTE_INSTANTIATION = (ID_OFFSET_INTERNAL + 0x003F), ID_SYSTEM_METADATA = (ID_OFFSET_INTERNAL + 0x0040), + ID_ENVIRONMENT_ITERATOR = (ID_OFFSET_INTERNAL + 0x0041), ID_EXTERNAL_INTERFACE_OFFSET = (ID_OFFSET_INTERNAL + 0x0080), ID_EXTERNAL_QA_INTERFACE_OFFSET = (ID_OFFSET_INTERNAL + 0xA000) diff --git a/Source/plugins/Configuration.h b/Source/plugins/Configuration.h index 440f27387..42b2b41a2 100644 --- a/Source/plugins/Configuration.h +++ b/Source/plugins/Configuration.h @@ -40,7 +40,7 @@ namespace Plugin { : Core::JSON::Container() , Key() , Value() - , Override(false) + , Override(RPC::Object::Environment::Scope::LOCAL) { Add(_T("key"), &Key); Add(_T("value"), &Value); @@ -85,14 +85,54 @@ namespace Plugin { return (*this); } + static std::vector List(const Core::JSON::ArrayType& environments) + { + std::vector environmentList; + + if (environments.IsSet() == true) { + Core::JSON::ArrayType::ConstIterator index(environments.Elements()); + while (index.Next() == true) { + if ((index.Current().Key.IsSet() == true) && (index.Current().Value.IsSet() == true)) { + RPC::Object::Environment env; + env.key = index.Current().Key.Value(); + env.value = index.Current().Value.Value(); + env.overriding = index.Current().Override.Value(); + environmentList.push_back(env); + } else { + SYSLOG(Logging::Startup, (_T("Failure in Substituting Value of Key:Value:[%s]:[%s]\n"), index.Current().Key.Value().c_str(), index.Current().Value.Value().c_str())); + } + } + } + return environmentList; + } + static RPC::Object::Environment Info(const string& env, RPC::Object::Environment::Scope overriding) + { + RPC::Object::Environment info; + size_t start = env.find_first_of(RPC::Object::EnvironmentSeparator); + if ((start != string::npos) && (start < env.length())) { + string key = env.substr(0, start); + string value = env.substr(start + 1); + + if ((key.empty() != true) && (value.empty() != true) && + ((value.at(0) == '\"') && (value.at(value.length()) == '\"'))) { + info.key = key; + info.value = value.substr(1, value.length() - 1); + info.overriding = overriding; + } else { + SYSLOG(Logging::Startup, (_T("Environment key:value fromat is invalid :[%s]:[%s]\n"), key.c_str(), value.c_str())); + } + } else { + SYSLOG(Logging::Startup, (_T("Invalid Enviroment value :[%s]\n"), env.c_str())); + } + return info; + } public: Core::JSON::String Key; Core::JSON::String Value; - Core::JSON::Boolean Override; + Core::JSON::EnumType Override; }; using EnvironmentList = Core::JSON::ArrayType; - static constexpr const TCHAR EnvFieldSeparator = _T(';'); class EXTERNAL RootConfig : public Core::JSON::Container { private: diff --git a/Source/plugins/IShell.h b/Source/plugins/IShell.h index 9dd3206ad..61f4bd375 100644 --- a/Source/plugins/IShell.h +++ b/Source/plugins/IShell.h @@ -235,9 +235,6 @@ namespace PluginHost { //! Substituted Config value virtual string Substitute(const string& input) const = 0; - //! Substituted environments list - virtual std::vector SubstituteList(const string& environments) const = 0; - virtual bool Resumed() const = 0; virtual Core::hresult Resumed(const bool value) = 0; diff --git a/Source/plugins/Shell.cpp b/Source/plugins/Shell.cpp index c91f58b83..e8d052665 100644 --- a/Source/plugins/Shell.cpp +++ b/Source/plugins/Shell.cpp @@ -69,8 +69,6 @@ namespace PluginHost if (locator.empty() == true) { locator = Locator(); } - string environments; - rootConfig.Environments.ToString(environments); RPC::Object definition(locator, className, Callsign(), @@ -84,7 +82,7 @@ namespace PluginHost SystemRootPath(), rootConfig.RemoteAddress.Value(), rootConfig.Configuration.Value(), - SubstituteList(environments)); + Plugin::Config::Environment::List(rootConfig.Environments)); result = handler->Instantiate(definition, waitTime, pid); }