Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SetEnv added for plugin Config as well #1764

Merged
merged 6 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 3 additions & 61 deletions Source/Thunder/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,64 +114,6 @@ namespace PluginHost {
// Configuration to get a server (PluginHost server) up and running.
class JSONConfig : public Core::JSON::Container {
public:
class Environment : public Core::JSON::Container {
public:
Environment()
: Core::JSON::Container()
, Key()
, Value()
, Override(false)
{
Add(_T("key"), &Key);
Add(_T("value"), &Value);
Add(_T("override"), &Override);
}
Environment(const Environment& copy)
: Core::JSON::Container()
, Key(copy.Key)
, Value(copy.Value)
, Override(copy.Override)
{
Add(_T("key"), &Key);
Add(_T("value"), &Value);
Add(_T("override"), &Override);
}
Environment(Environment&& move) noexcept
: Core::JSON::Container()
, Key(std::move(move.Key))
, Value(std::move(move.Value))
, Override(std::move(move.Override))
{
Add(_T("key"), &Key);
Add(_T("value"), &Value);
Add(_T("override"), &Override);
}
~Environment() override = default;
Environment& operator=(const Environment& RHS)
{
Key = RHS.Key;
Value = RHS.Value;
Override = RHS.Override;

return (*this);
}
Environment& operator=(Environment&& move) noexcept
{
if (this != &move) {
Key = std::move(move.Key);
Value = std::move(move.Value);
Override = std::move(move.Override);
}

return (*this);
}

public:
Core::JSON::String Key;
Core::JSON::String Value;
Core::JSON::Boolean Override;
};

class ProcessSet : public Core::JSON::Container {
public:
ProcessSet()
Expand Down Expand Up @@ -526,7 +468,7 @@ namespace PluginHost {
Core::JSON::String Configs;
Core::JSON::String EthernetCard;
Core::JSON::ArrayType<Plugin::Config> Plugins;
Core::JSON::ArrayType<Environment> Environments;
Core::JSON::ArrayType<Plugin::Config::Environment> Environments;
Core::JSON::ArrayType<Core::JSON::EnumType<PluginHost::IShell::reason>> ExitReasons;
Core::JSON::DecSInt32 Latitude;
Core::JSON::DecSInt32 Longitude;
Expand Down Expand Up @@ -773,12 +715,12 @@ namespace PluginHost {
}

bool status = true;
Core::JSON::ArrayType<JSONConfig::Environment>::ConstIterator index(static_cast<const JSONConfig&>(config).Environments.Elements());
Core::JSON::ArrayType<Plugin::Config::Environment>::ConstIterator index(static_cast<const JSONConfig&>(config).Environments.Elements());
while (index.Next() == true) {
if ((index.Current().Key.IsSet() == true) && (index.Current().Value.IsSet() == true)) {
string value = _substituter.Substitute(index.Current().Value.Value(), nullptr);
if (value.empty() != true) {
status = Core::SystemInfo::SetEnvironment(index.Current().Key.Value(), value, index.Current().Override.Value());
status = Core::SystemInfo::SetEnvironment(index.Current().Key.Value(), value, ((index.Current().Override.Value() == RPC::Object::Environment::Scope::GLOBAL) ? true : false));
if (status != true) {
SYSLOG(Logging::Startup, (_T("Failure in setting Key:Value:[%s]:[%s]\n"), index.Current().Key.Value().c_str(), index.Current().Value.Value().c_str()));
}
Expand Down
4 changes: 3 additions & 1 deletion Source/Thunder/IRemoteInstantiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace PluginHost {
struct IRemoteInstantiation : virtual public Core::IUnknown {

enum { ID = RPC::IDS::ID_REMOTE_INSTANTIATION };
using IEnvironmentIterator = RPC::IIteratorType<RPC::Object::Environment, RPC::ID_ENVIRONMENT_ITERATOR>;

~IRemoteInstantiation() override = default;

Expand Down Expand Up @@ -56,7 +57,8 @@ namespace PluginHost {
const string& systemRootPath,
const uint8_t threads,
const int8_t priority,
const string configuration) = 0;
const string configuration,
IEnvironmentIterator* const& environments) = 0;
};
}
}
70 changes: 64 additions & 6 deletions Source/Thunder/PluginServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ namespace PluginHost {
DYNAMIC
};

using Services = std::unordered_map<string, Service*>;

private:
using BaseClass = PluginHost::Service;
using Jobs = Core::ThrottleQueueType<Core::ProxyType<Core::IDispatch>, ServiceMap&>;
Expand Down Expand Up @@ -1277,16 +1279,33 @@ namespace PluginHost {
string Substitute(const string& input) const override {
return (_administrator.Configuration().Substitute(input, PluginHost::Service::Configuration()));
}
Core::hresult Metadata(string& info /* @out */) const override {
Core::hresult Metadata(string& info /* @out */) const override {
Metadata::Service result;
GetMetadata(result);
result.ToString(info);
return (Core::ERROR_NONE);
}
std::vector<RPC::Object::Environment> SubstituteList(const std::vector<RPC::Object::Environment>& environments) const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we want to create a "new" list. Can we not just reuse the old list ? It ssaves a lot of memory and if we call this the assumption is that there is no need to "save" the old one..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed

std::vector<RPC::Object::Environment> 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(env);
} 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<RPC::Object&>(object).Environments(SubstituteList(object.Environments()));

void* result(_administrator.Instantiate(object, waitTime, sessionId, DataPath(), PersistentPath(), VolatilePath(), _administrator.Configuration().LinkerPluginPaths()));

if (result != nullptr) {
Expand Down Expand Up @@ -1499,7 +1518,9 @@ namespace PluginHost {
else {
uint32_t pid;
Core::ServiceAdministrator::Instance().ReleaseLibrary(std::move(_library));

string environments;
PluginHost::Service::Configuration().Root.Environments.ToString(environments);

RPC::Object definition(locator,
classNameString,
Callsign(),
Expand All @@ -1512,7 +1533,8 @@ namespace PluginHost {
PluginHost::Service::Configuration().Root.HostType(),
SystemRootPath(),
PluginHost::Service::Configuration().Root.RemoteAddress.Value(),
PluginHost::Service::Configuration().Root.Configuration.Value());
PluginHost::Service::Configuration().Root.Configuration.Value(),
Plugin::Config::Environment::List(PluginHost::Service::Configuration().Root.Environments));

newIF = reinterpret_cast<IPlugin*>(Instantiate(definition, _administrator.Configuration().OutOfProcessWaitTime(), pid));
if (newIF == nullptr) {
Expand Down Expand Up @@ -2007,6 +2029,10 @@ namespace PluginHost {
if (instantiation == nullptr) {
result = Core::ERROR_ILLEGAL_STATE;
} else {

using Iterator = IRemoteInstantiation::IEnvironmentIterator;
Iterator* environment = Core::Service<RPC::IteratorType<Iterator>>::Create<Iterator>(_object.Environments());

result = instantiation->Instantiate(
RPC::Communicator::RemoteConnection::Id(),
_object.Locator(),
Expand All @@ -2019,7 +2045,8 @@ namespace PluginHost {
_object.SystemRootPath(),
_object.Threads(),
_object.Priority(),
_object.Configuration());
_object.Configuration(),
environment);

instantiation->Release();
}
Expand Down Expand Up @@ -2399,7 +2426,8 @@ namespace PluginHost {
const string& systemRootPath,
const uint8_t threads,
const int8_t priority,
const string configuration) override
const string configuration,
IRemoteInstantiation::IEnvironmentIterator* const& environments) override
{
string persistentPath(_comms.PersistentPath());
string dataPath(_comms.DataPath());
Expand All @@ -2411,9 +2439,17 @@ namespace PluginHost {
volatilePath += callsign + '/';
}

std::vector<RPC::Object::Environment> _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);
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);

Expand All @@ -2424,6 +2460,17 @@ namespace PluginHost {
INTERFACE_ENTRY(IRemoteInstantiation)
END_INTERFACE_MAP

private:
std::vector<RPC::Object::Environment> SubstituteList(const string& callsign, const std::vector<RPC::Object::Environment>& environments) const
{
std::vector<RPC::Object::Environment> substitutedList;
Core::ProxyType<Service> service = _parent.GetService(callsign);
if (service.IsValid() == true) {
substitutedList = service->SubstituteList(environments);
}
return substitutedList;
}

private:
mutable uint32_t _refCount;
ServiceMap& _parent;
Expand Down Expand Up @@ -3064,6 +3111,17 @@ namespace PluginHost {

_adminLock.Unlock();
}
inline Core::ProxyType<Service> GetService(const string& callsign)
{
Core::ProxyType<Service> service;
for (std::pair<const string, Core::ProxyType<Service>>& entry : _services) {
if (entry.first == callsign) {
service = entry.second;
break;
}
}
return service;
}
inline Iterator Services()
{
Shells workingList;
Expand Down
21 changes: 20 additions & 1 deletion Source/ThunderPlugin/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -202,6 +202,7 @@ POP_WARNING()
string ProxyStubPath;
string PostMortemPath;
string SystemRootPath;
std::vector<RPC::Object::Environment> Environments;
const TCHAR* User;
const TCHAR* Group;
uint8_t Threads;
Expand Down Expand Up @@ -250,6 +251,13 @@ POP_WARNING()
case 'S':
SystemRootPath = Core::Directory::Normalize(Strip(argument));
break;
case 'e':
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;
Expand Down Expand Up @@ -588,6 +596,8 @@ int main(int argc, char** argv)
printf(" [-d <data path>]\n");
printf(" [-v <volatile path>]\n");
printf(" [-f <linker_path>...\n");
printf(" [-e/-E <environment values>...]\n");
printf(" e: means set as local scope, E: means set as global scope\n");
printf(" [-a <app path>]\n");
printf(" [-m <proxy stub library path>]\n");
printf(" [-P <post mortem path>]\n\n");
Expand Down Expand Up @@ -664,6 +674,15 @@ int main(int argc, char** argv)
Core::ProcessCurrent().User(string(options.User));
}

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()));
}
}
}

process.Startup(options.Threads, remoteNode, callsign);

// Register an interface to handle incoming requests for interfaces.
Expand Down
8 changes: 8 additions & 0 deletions Source/com/Communicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,4 +575,12 @@ namespace RPC {
constexpr uint32_t RPC::ProcessShutdown::DestructionStackSize;

}

ENUM_CONVERSION_BEGIN(RPC::Object::Environment::Scope)

{ RPC::Object::Environment::Scope::LOCAL, _TXT("Local") },
{ RPC::Object::Environment::Scope::GLOBAL, _TXT("Global") },

ENUM_CONVERSION_END(RPC::Object::Environment::Scope)

}
Loading
Loading