1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //-----------------------------------------------------------------------------
19 //-----------------------------------------------------------------------------
21 #include "administered_module.h"
22 #include "module_admin_itf.h"
23 #include "patchman_tester.h"
24 #include "patchman_constants.h"
27 //-------------------------------------------------------------------------------------------------
29 //-------------------------------------------------------------------------------------------------
32 using namespace NLMISC
;
33 using namespace NLNET
;
34 using namespace PATCHMAN
;
37 //-----------------------------------------------------------------------------
38 // methods CAdministeredModuleBase - ctors / dtors
39 //-----------------------------------------------------------------------------
41 CAdministeredModuleBase::CAdministeredModuleBase()
47 NLMISC::CSString
CAdministeredModuleBase::init(const TParsedCommandLine
&initInfo
)
49 CAdministeredModuleBaseSkel::init(this);
50 // prevent double initialialisation (given that we are using virtual inherritance,
51 // this init can be called more than once for the same module)
56 // initialise the module base...
57 CModuleBase::initModule(initInfo
);
59 // initialise the state variables
60 setStateVariable("State","Initialising");
67 //-----------------------------------------------------------------------------
68 // methods CAdministeredModuleBase - hooks for methods that this interface implements and that must be called from the parent class
69 //-----------------------------------------------------------------------------
71 void CAdministeredModuleBase::onModuleUp(IModuleProxy
*module
)
73 // if the module coming up is an SPM module then we call it 'dad'
74 if (CSString(module
->getModuleManifest()).contains(ManifestEntryIsAdministrator
))
76 _PatchManagers
.insert(module
);
77 registerProgress("ServerPatchManager Connected: "+module
->getModuleName()+" ("+module
->getModuleManifest()+")");
81 void CAdministeredModuleBase::onModuleDown(IModuleProxy
*module
)
83 // if the module going down is an SPM module then remove it from our lists
84 if (_PatchManagers
.find(module
)!=_PatchManagers
.end())
86 _PatchManagers
.erase(module
);
87 registerProgress("ServerPatchManager Disconnected: "+module
->getModuleName()+" ("+module
->getModuleManifest()+")");
91 void CAdministeredModuleBase::onModuleUpdate()
93 H_AUTO(CAdministeredModuleBase_onModuleUpdate
);
94 // if the state has changed then broadcast the new state info
95 if (_LastBroadcastState
!= getStateString())
101 //bool CAdministeredModuleBase::onDispatchMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message)
103 // return CAdministeredModuleBaseSkel::onDispatchMessage(sender,message);
107 //-----------------------------------------------------------------------------
108 // methods CAdministeredModuleBase - callbackf for treating module messages
109 //-----------------------------------------------------------------------------
111 void CAdministeredModuleBase::executeCommand(NLNET::IModuleProxy
*sender
, const NLMISC::CSString
&cmdline
, const NLMISC::CSString
&originator
)
113 // create a displayer to gather the output of the command
114 class SStringDisplayer
: public IDisplayer
118 void doDisplay( const CLog::TDisplayInfo
& args
, const char *message
)
124 SStringDisplayer stringDisplayer
;
125 log
.addDisplayer(&stringDisplayer
);
127 // execute the command
128 registerProgress(NLMISC::toString("exec '%s' (via '%s'): '%s'", originator
.c_str(), sender
->getModuleName().c_str(), cmdline
.c_str()));
129 ICommand::execute(this->getModuleName()+'.'+cmdline
.strip(),log
);
131 // send a reply message to the originating service
132 CServerPatchManagerProxy
manager(sender
);
133 manager
.executedCommandResult(this,originator
,cmdline
,stringDisplayer
.Data
);
137 //-----------------------------------------------------------------------------
138 // methods CAdministeredModuleBase - methods for managing state variables
139 //-----------------------------------------------------------------------------
141 void CAdministeredModuleBase::registerError(const NLMISC::CSString
& value
) const
144 setStateVariable("Error",NLMISC::toString("[%d]",_ErrorCount
)+value
);
145 nlwarning("%s: ERROR: %s",CModuleBase::getModuleName().c_str(),value
.c_str());
148 void CAdministeredModuleBase::registerProgress(const NLMISC::CSString
& value
) const
150 setStateVariable("Latest",value
);
151 nlinfo("%s: %s",CModuleBase::getModuleName().c_str(),value
.c_str());
154 void CAdministeredModuleBase::setStateVariable(const NLMISC::CSString
& variableName
, const NLMISC::CSString
& value
) const
156 // if the state variable is in fact unchanged then just drop out as there is nothing real to do
157 if (_StateVariables
[variableName
] == value
)
162 // set the state variable value
163 _StateVariables
[variableName
]= value
;
166 void CAdministeredModuleBase::appendStateVariable(const NLMISC::CSString
& variableName
, const NLMISC::CSString
& value
) const
168 // if the state variable is in fact unchanged then just drop out as there is nothing real to do
174 // if the state variable isn't currently empty then add a separating space before the new value
175 if (!_StateVariables
[variableName
].empty())
177 _StateVariables
[variableName
]+= ' ';
180 // append the new value to the state variable
181 _StateVariables
[variableName
]+= value
;
184 const NLMISC::CSString
& CAdministeredModuleBase::getStateVariable(const NLMISC::CSString
& variableName
) const
186 // setup a static 'emptyString' to return a refference to if requested variables are not found
187 static NLMISC::CSString emptyString
;
189 return (_StateVariables
.find(variableName
)==_StateVariables
.end())? emptyString
: _StateVariables
[variableName
];
192 NLMISC::CSString
CAdministeredModuleBase::getStateString() const
194 // setup a result variable to build the output string in
195 NLMISC::CSString result
;
197 // add each variable to the result string in turn
198 for (TStateVariables::iterator it
= _StateVariables
.begin(); it
!=_StateVariables
.end(); ++it
)
206 result
+= it
->second
.quoteIfNotAtomic();
209 // all done so return the constructed string
213 void CAdministeredModuleBase::clearStateVariable(const NLMISC::CSString
& variableName
) const
215 _StateVariables
.erase(variableName
);
218 void CAdministeredModuleBase::clearAllStateVariables() const
220 _StateVariables
.clear();
223 void CAdministeredModuleBase::broadcastStateInfo() const
225 // generate the state string that we need to dispatch to any listening modules
226 CSString stateString
= getStateString();
228 // send an update message to any connected SPM modules
229 for (TPatchManagers::const_iterator it
=_PatchManagers
.begin(); it
!=_PatchManagers
.end(); ++it
)
231 CServerPatchManagerProxy
spm(*it
);
232 spm
.declareState(const_cast<CAdministeredModuleBase
*>(this),stateString
);
235 // after broadcasting the state info the 'state has changed' flag can be set to false
236 _LastBroadcastState
= stateString
;
239 //-----------------------------------------------------------------------------
240 // class CAdministeredModuleWrapper
241 //-----------------------------------------------------------------------------
243 CAdministeredModuleWrapper::CAdministeredModuleWrapper()
245 _AdministeredModuleBase
= NULL
;
248 NLMISC::CSString
CAdministeredModuleWrapper::init(CAdministeredModuleBase
* administeredModuleBase
)
250 _AdministeredModuleBase
= administeredModuleBase
;
254 void CAdministeredModuleWrapper::registerError(const NLMISC::CSString
& value
) const
256 if (_AdministeredModuleBase
!=NULL
)
258 _AdministeredModuleBase
->registerError(value
);
262 nlwarning("Error: %s",value
.c_str());
266 void CAdministeredModuleWrapper::registerProgress(const NLMISC::CSString
& value
) const
268 if (_AdministeredModuleBase
!=NULL
)
270 _AdministeredModuleBase
->registerProgress(value
);
274 nlinfo("Latest: %s",value
.c_str());
278 void CAdministeredModuleWrapper::setStateVariable(const NLMISC::CSString
& variableName
, const NLMISC::CSString
& value
) const
280 if (_AdministeredModuleBase
!=NULL
)
282 _AdministeredModuleBase
->setStateVariable(variableName
,value
);
286 nldebug("Setting: %s = %s",variableName
.c_str(),value
.c_str());
290 void CAdministeredModuleWrapper::appendStateVariable(const NLMISC::CSString
& variableName
, const NLMISC::CSString
& value
) const
292 if (_AdministeredModuleBase
!=NULL
)
294 _AdministeredModuleBase
->appendStateVariable(variableName
,value
);
298 nldebug("Appending: %s += %s",variableName
.c_str(),value
.c_str());
302 void CAdministeredModuleWrapper::clearStateVariable(const NLMISC::CSString
& variableName
) const
304 if (_AdministeredModuleBase
!=NULL
)
306 _AdministeredModuleBase
->clearStateVariable(variableName
);
310 nldebug("Clearing: %s",variableName
.c_str());
314 void CAdministeredModuleWrapper::clearAllStateVariables() const
316 if (_AdministeredModuleBase
!=NULL
)
318 _AdministeredModuleBase
->clearAllStateVariables();
322 nlinfo("Clearing all state variables...");
326 void CAdministeredModuleWrapper::broadcastStateInfo() const
328 if (_AdministeredModuleBase
!=NULL
)
330 _AdministeredModuleBase
->broadcastStateInfo();