static void cbView(CMessage &msgin, const std::string &serviceName, TServiceId sid)
{
	// receive an view answer from the service
	TServices::iterator sit = findService(sid);

	uint32 rid;
	msgin.serial(rid);

	TAdminViewResult answer;
	TAdminViewVarNames varNames;
	TAdminViewValues values;

	while ((uint32)msgin.getPos() < msgin.length())
	{
		varNames.clear();
		values.clear();

		// adding default row

		uint32 i, nb;
		string var, val;

		msgin.serial(nb);
		for (i = 0; i < nb; i++)
		{
			msgin.serial(var);
			varNames.push_back(var);
		}

		msgin.serial(nb);
		for (i = 0; i < nb; i++)
		{
			msgin.serial(val);
			values.push_back(val);
		}
		answer.push_back(SAdminViewRow(varNames,values));
	}
	aesAddRequestAnswer(rid, answer);

	// remove the waiting request
	for (uint i = 0; i < (*sit).WaitingRequestId.size();)
	{
		if ((*sit).WaitingRequestId[i] == rid)
		{
			(*sit).WaitingRequestId.erase((*sit).WaitingRequestId.begin()+i);
		}
		else
		{
			i++;
		}
	}
}
Beispiel #2
0
static void cbServGetView (CMessage &msgin, const std::string &/* serviceName */, TServiceId sid)
{
	uint32 rid;
	string rawvarpath;

	msgin.serial (rid);
	msgin.serial (rawvarpath);

	Requests.push_back (CRequest(rid, sid));

	TAdminViewResult answer;
	// just send the view in async mode, don't retrieve the answer
	serviceGetView (rid, rawvarpath, answer, true);
	nlassert (answer.empty());
}
void aesAddRequestAnswer(uint32 rid, const TAdminViewResult& answer)
{
	for (uint i = 0 ; i < Requests.size(); i++)
	{
		if (Requests[i].Id == rid)
		{
			for (uint t = 0; t < answer.size(); t++)
			{
				if (!answer[t].VarNames.empty() && answer[t].VarNames[0] == "__log")
				{	nlassert(answer[t].VarNames.size() == 1); }
				else
				{	nlassert(answer[t].VarNames.size() == answer[t].Values.size()); }
				Requests[i].Answers.push_back(SAdminViewRow(answer[t].VarNames, answer[t].Values));
			}
			Requests[i].NbReceived++;
			nldebug("REQUEST: ++ i %d rid %d NbWaiting %d NbReceived+ %d", i, Requests[i].Id, Requests[i].NbWaiting, Requests[i].NbReceived);
			return;
		}
	}
	// we received an unknown request, forget it
	nlwarning("Receive an answer for unknown request %d", rid);
}
Beispiel #4
0
// this callback is used to create a view for the admin system
void serviceGetView (uint32 rid, const string &rawvarpath, TAdminViewResult &answer, bool async)
{
	string str;
	CLog logDisplayVars;
	CLightMemDisplayer mdDisplayVars;
	logDisplayVars.addDisplayer (&mdDisplayVars);
	mdDisplayVars.setParam (4096);

	CVarPath varpath(rawvarpath);

	if (varpath.empty())
		return;

	// special case for named command handler
	if (CCommandRegistry::getInstance().isNamedCommandHandler(varpath.Destination[0].first))
	{
		varpath.Destination[0].first += "."+varpath.Destination[0].second;
		varpath.Destination[0].second = "";
	}

	if (varpath.isFinal())
	{
		TAdminViewVarNames varNames;
		TAdminViewValues values;

		// add default row
		varNames.push_back ("service");
		values.push_back (IService::getInstance ()->getServiceUnifiedName());

		for (uint j = 0; j < varpath.Destination.size (); j++)
		{
			string cmd = varpath.Destination[j].first;

			// replace = with space to execute the command
			string::size_type eqpos = cmd.find("=");
			if (eqpos != string::npos)
			{
				cmd[eqpos] = ' ';
				varNames.push_back(cmd.substr(0, eqpos));
			}
			else
				varNames.push_back(cmd);

			mdDisplayVars.clear ();
			ICommand::execute(cmd, logDisplayVars, !ICommand::isCommand(cmd));
			const std::deque<std::string>	&strs = mdDisplayVars.lockStrings();

			if (ICommand::isCommand(cmd))
			{
				// we want the log of the command
				if (j == 0)
				{
					varNames.clear ();
					varNames.push_back ("__log");
					values.clear ();
				}

				values.push_back ("----- Result from "+IService::getInstance()->getServiceUnifiedName()+" of command '"+cmd+"'\n");
				for (uint k = 0; k < strs.size(); k++)
				{
					values.push_back (strs[k]);
				}
			}
			else
			{

				if (strs.size()>0)
				{
					str = strs[0].substr(0,strs[0].size()-1);
					// replace all spaces into udnerscore because space is a reserved char
					for (uint i = 0; i < str.size(); i++) if (str[i] == ' ') str[i] = '_';
				}
				else
				{
					str = "???";
				}
				values.push_back (str);
				nlinfo ("ADMIN: Add to result view '%s' = '%s'", varpath.Destination[j].first.c_str(), str.c_str());
			}
			mdDisplayVars.unlockStrings();
		}

		if (!async)
			answer.push_back (SAdminViewRow(varNames, values));
		else
		{
			addRequestWaitingNb (rid);
			addRequestAnswer (rid, varNames, values);
		}
	}
	else
	{
		// there s an entity in the varpath, manage this case

		TAdminViewVarNames *varNames=0;
		TAdminViewValues *values=0;

		// varpath.Destination		contains the entity number
		// subvarpath.Destination	contains the command name

		for (uint i = 0; i < varpath.Destination.size (); i++)
		{
			CVarPath subvarpath(varpath.Destination[i].second);

			for (uint j = 0; j < subvarpath.Destination.size (); j++)
			{
				// set the variable name
				string cmd = subvarpath.Destination[j].first;

				if (isRemoteCommand(cmd))
				{
					if (async && RemoteClientCallback != 0)
					{
						// ok we have to send the request to another side, just send and wait
						addRequestWaitingNb (rid);
						RemoteClientCallback (rid, cmd, varpath.Destination[i].first);
					}
				}
				else
				{
					// replace = with space to execute the command
					string::size_type eqpos = cmd.find("=");
					if (eqpos != string::npos)
					{
						cmd[eqpos] = ' ';
						// add the entity
						cmd.insert(eqpos, " "+varpath.Destination[i].first);
					}
					else
					{
						// add the entity
						cmd += " "+varpath.Destination[i].first;
					}

					mdDisplayVars.clear ();
					ICommand::execute(cmd, logDisplayVars, true);
					const std::deque<std::string>	&strs = mdDisplayVars.lockStrings();
					for (uint k = 0; k < strs.size(); k++)
					{
						const string &str = strs[k];

						string::size_type pos = str.find(" ");
						if(pos == string::npos)
							continue;

						string entity = str.substr(0, pos);
						string value = str.substr(pos+1, str.size()-pos-2);
						for (uint u = 0; u < value.size(); u++) if (value[u] == ' ') value[u] = '_';

						// look in the array if we already have something about this entity

						if (!async)
						{
							uint y;
							for (y = 0; y < answer.size(); y++)
							{
								if (answer[y].Values[1] == entity)
								{
									// ok we found it, just push_back new stuff
									varNames = &(answer[y].VarNames);
									values = &(answer[y].Values);
									break;
								}
							}
							if (y == answer.size ())
							{
								answer.push_back (SAdminViewRow());

								varNames = &(answer[answer.size()-1].VarNames);
								values = &(answer[answer.size()-1].Values);

								// don't add service if we want an entity
		// todo when we work on entity, we don't need service name and server so we should remove them and collapse all var for the same entity
								varNames->push_back ("service");
								string name = IService::getInstance ()->getServiceUnifiedName();
								values->push_back (name);

								// add default row
								varNames->push_back ("entity");
								values->push_back (entity);
							}

							varNames->push_back (cmd.substr(0, cmd.find(" ")));
							values->push_back (value);
						}
						else
						{
							addRequestWaitingNb (rid);

							TAdminViewVarNames varNames;
							TAdminViewValues values;
							varNames.push_back ("service");
							string name = IService::getInstance ()->getServiceUnifiedName();
							values.push_back (name);

							// add default row
							varNames.push_back ("entity");
							values.push_back (entity);

							varNames.push_back (cmd.substr(0, cmd.find(" ")));
							values.push_back (value);

							addRequestAnswer (rid, varNames, values);
						}
						nlinfo ("ADMIN: Add to result view for entity '%s', '%s' = '%s'", varpath.Destination[i].first.c_str(), subvarpath.Destination[j].first.c_str(), str.c_str());
					}
					mdDisplayVars.unlockStrings();
				}
			}
		}
	}
}