예제 #1
0
void treatRequestForOfflineService(uint32 rid, const string& serviceName, const string& viewStr)
{
	CVarPath subvarpath(viewStr);

	addRequestWaitingNb(rid);

	TAdminViewVarNames varNames;
	TAdminViewValues values;

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

	for (uint k = 0; k < subvarpath.Destination.size(); k++)
	{
		size_t pos = subvarpath.Destination[k].first.find("=");
		if (pos != string::npos)
			varNames.push_back(subvarpath.Destination[k].first.substr(0, pos));
		else
			varNames.push_back(subvarpath.Destination[k].first);

		string val = "???";
		// handle special case of non running service
		if (subvarpath.Destination[k].first == "State")
		{
			// lookup the alias, command to execute, execution path and defined command args for the given service
			string alias, command, path, arg;
			getServiceLaunchInfo(serviceName,alias,command,path,arg);
			val = getOfflineServiceState(alias,path);
		}
		else if (subvarpath.Destination[k].first == "State=1" ||
				 subvarpath.Destination[k].first == "State=2" ||
				 subvarpath.Destination[k].first == "State=3")
		{
			// we want to start the service
			if (startService(serviceName))
				val = "Launching";
			else
				val = "Failed";
		}
		else if (subvarpath.Destination[k].first == "State=0" ||
				 subvarpath.Destination[k].first == "State=-1" ||
				 subvarpath.Destination[k].first == "State=-2")
		{
			// lookup the alias, command to execute, execution path and defined command args for the given service
			string alias, command, path, arg;
			bool ok= getServiceLaunchInfo(serviceName,alias,command,path,arg);
			if (ok) writeServiceLaunchCtrl(alias,path,true,LaunchCtrlStop);
			if (ok) writeServiceLaunchCtrl(alias,path,false,LaunchCtrlStop);
			val= "Stopping";
		}

		values.push_back(val);
	}

	aesAddRequestAnswer(rid, varNames, values);
	nlinfo("REQUEST: Sent and received view '%s' to offline service '%s'", viewStr.c_str(), serviceName.c_str());
}
예제 #2
0
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++;
		}
	}
}
예제 #3
0
void aesAddRequestAnswer(uint32 rid, TAdminViewVarNames& varNames, const TAdminViewValues& values)
{
	if (!varNames.empty() && varNames[0] == "__log")
	{	nlassert(varNames.size() == 1); }
	else
	{	nlassert(varNames.size() == values.size()); }

	for (uint i = 0 ; i < Requests.size(); i++)
	{
		if (Requests[i].Id == rid)
		{
			Requests[i].Answers.push_back(SAdminViewRow(varNames, 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);
}
예제 #4
0
void cleanRequests()
{
	uint32 currentTime = CTime::getSecondsSince1970();

	// just a debug check
	for (uint t = 0 ; t < Requests.size(); t++)
	{
		uint32 NbWaiting = Requests[t].NbWaiting;
		uint32 NbReceived = Requests[t].NbReceived;

		uint32 NbRef = 0;
		for (uint j = 0; j < Services.size(); j++)
		{
			if (Services[j].Connected)
			{
				for (uint k = 0; k < Services[j].WaitingRequestId.size(); k++)
				{
					if(Services[j].WaitingRequestId[k] == Requests[t].Id)
					{
						NbRef++;
					}
				}
			}
		}
		nlinfo("REQUEST: Waiting request %d: NbRef %d NbWaiting %d NbReceived %d", Requests[t].Id, NbRef, NbWaiting, NbReceived);

		if (NbRef != NbWaiting - NbReceived)
		{
			nlwarning("REQUEST: **** i %d rid %d -> NbRef(%d) != NbWaiting(%d) - NbReceived(%d) ", t, Requests[t].Id, NbRef, NbWaiting, NbReceived);
		}
	}

	for (uint i = 0 ; i < Requests.size();)
	{
		// timeout
		if (currentTime >= Requests[i].Time+RequestTimeout)
		{
			nlwarning("REQUEST: Request %d timeouted, only %d on %d services have replied", Requests[i].Id, Requests[i].NbReceived, Requests[i].NbWaiting);

			TAdminViewVarNames varNames;
			TAdminViewValues values;

			varNames.push_back("service");
			for (uint j = 0; j < Services.size(); j++)
			{
				if (Services[j].Connected)
				{
					for (uint k = 0; k < Services[j].WaitingRequestId.size(); k++)
					{
						if(Services[j].WaitingRequestId[k] == Requests[i].Id)
						{
							// this services didn't answer
							string s;
							if(Services[j].AliasName.empty())
								s = Services[j].ShortName;
							else
								s = Services[j].AliasName;
							s += "-"+toString(Services[j].ServiceId);
							s += "((TIMEOUT))";
							values.clear();
							values.push_back(s);
							aesAddRequestAnswer(Requests[i].Id, varNames, values);
							break;
						}
					}
				}
			}
			if (Requests[i].NbWaiting != Requests[i].NbReceived)
			{
				nlwarning("REQUEST: **** i %d rid %d -> Requests[i].NbWaiting(%d) != Requests[i].NbReceived(%d)", i, Requests[i].Id, Requests[i].NbWaiting, Requests[i].NbReceived);
				nlwarning("REQUEST: Need to add dummy answer");
				values.clear();
				values.push_back("UnknownService");
				while (Requests[i].NbWaiting != Requests[i].NbReceived)
					aesAddRequestAnswer(Requests[i].Id, varNames, values);
			}
		}

		if (Requests[i].NbWaiting <= Requests[i].NbReceived)
		{
			// the request is over, send to the php

			CMessage msgout("VIEW");
			msgout.serial(Requests[i].Id);

			for (uint j = 0; j < Requests[i].Answers.size(); j++)
			{
				msgout.serialCont(Requests[i].Answers[j].VarNames);
				msgout.serialCont(Requests[i].Answers[j].Values);
			}

			if (Requests[i].SId == TServiceId(0))
			{
				nlinfo("REQUEST: Receive an answer for the fake request %d with %d answers", Requests[i].Id, Requests[i].Answers.size());
				for (uint j = 0; j < Requests[i].Answers.size(); j++)
				{
					uint k;
					for (k = 0; k < Requests[i].Answers[j].VarNames.size(); k++)
					{
						InfoLog->displayRaw("%-20s ", Requests[i].Answers[j].VarNames[k].c_str());
					}
					InfoLog->displayRawNL("");
					for (k = 0; k < Requests[i].Answers[j].Values.size(); k++)
					{
						InfoLog->displayRaw("%-20s", Requests[i].Answers[j].Values[k].c_str());
					}
					InfoLog->displayRawNL("");
					InfoLog->displayRawNL("----------------------------------------------");
				}
			}
			else
				CUnifiedNetwork::getInstance()->send(Requests[i].SId, msgout);

			// set to 0 to erase it
			Requests[i].NbWaiting = 0;
			nldebug("REQUEST: ++ i %d rid %d NbWaiting0 %d NbReceived %d", i, Requests[i].Id, Requests[i].NbWaiting, Requests[i].NbReceived);
		}

		if (Requests[i].NbWaiting == 0)
		{
			Requests.erase(Requests.begin()+i);
		}
		else
		{
			i++;
		}
	}
}
예제 #5
0
파일: admin.cpp 프로젝트: mixxit/solinia
// 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();
				}
			}
		}
	}
}