FACT++  1.0
ServiceList.cc
Go to the documentation of this file.
1 // **************************************************************************
33 // **************************************************************************
34 #include "ServiceList.h"
35 
36 #include <sstream>
37 
38 #include "WindowLog.h"
39 #include "Converter.h"
40 
41 #include "tools.h"
42 #include "Time.h"
43 
44 using namespace std;
45 
46 // --------------------------------------------------------------------------
47 //
59 //
60 ServiceList::ServiceList(const char *type, ostream &out) :
61  wout(out), fDimServers("DIS_DNS/SERVER_LIST", const_cast<char*>(""), this),
62  fType(type), fHandler(0)
63 {
64 }
65 
66 // --------------------------------------------------------------------------
67 //
75 //
76 ServiceList::ServiceList(ostream &out) :
77  wout(out), fDimServers("DIS_DNS/SERVER_LIST", const_cast<char*>(""), this),
78  fType(""), fHandler(0)
79 {
80 }
81 
82 // --------------------------------------------------------------------------
83 //
85 //
87 {
88  for (ServerMap::iterator i=fServerList.begin(); i!=fServerList.end(); i++)
89  {
90  delete i->second.first;
91  delete i->second.second;
92  }
93 }
94 
95 // --------------------------------------------------------------------------
96 //
104 //
106 {
107  if (getInfo()==&fDimServers)
109  else
111 
112  if (fHandler)
113  {
114  fHandler->itsService = 0;
116  }
117 }
118 
119 // --------------------------------------------------------------------------
120 //
132 DimInfo *ServiceList::CreateDimInfo(const string &str, const string &svc) const
133 {
134  return new DimInfo((str+'/'+svc).c_str(),
135  const_cast<char*>(""),
136  const_cast<ServiceList*>(this));
137 }
138 
139 // --------------------------------------------------------------------------
140 //
150 {
151  // Get the received string from the handler
152  const string str = fDimServers.getString();
153 
154  // Check if it starts with + or -
155  if (str[0]!='-' && str[0]!='+')
156  {
157  // If it doesn't start with + or - remove all existing servers
158  // we have received a full server list
159  for (ServerMap::iterator i=fServerList.begin(); i!=fServerList.end(); i++)
160  {
161  delete i->second.first;
162  delete i->second.second;
163 
164  ServiceMap::iterator x = fServiceList.find(i->first);
165  fServiceList.erase(x);
166  //wout << "Delete: " << i->first << endl;
167  }
168 
169  fServerList.clear();
170  }
171 
172  // Create a stringstream to tokenize the received string
173  stringstream stream(str);
174 
175  // Loop over the seperating tokens
176  string buffer;
177  while (getline(stream, buffer, '|'))
178  {
179  // The first part before the first @ is the server name
180  const string server = buffer.substr(0, buffer.find_first_of('@'));
181  if (server.empty())
182  continue;
183 
184  // If it starts with a - we have to remove an entry
185  if (server[0]=='-')
186  {
187  const string trunc = server.substr(1);
188 
189  // Check if this server is not found in the list.
190  // This should never happen if Dim works reliable
191  const ServerMap::iterator v = fServerList.find(trunc);
192  if (v==fServerList.end())
193  {
194  wout << kRed << "Server '" << trunc << "' not in list as it ought to be." << endl;
195  continue;
196  }
197 
198  // Remove the server from the server list
199  delete v->second.first;
200  delete v->second.second;
201  fServerList.erase(v);
202 
203  // Remove the server from the command list
204  ServiceMap::iterator w = fServiceList.find(trunc);
205  fServiceList.erase(w);
206 
207  wout << " -> " << Time().GetAsStr() << " - " << trunc << "/SERVICE_LIST: Disconnected." << endl;
208  //wout << "Remove: " << server << endl;
209  continue;
210  }
211 
212  // If it starts with a + we have to add an entry
213  if (server[0]=='+')
214  {
215  const string trunc = server.substr(1);
216 
217  // Check if this server is already in the list.
218  // This should never happen if Dim works reliable
219  const ServerMap::iterator v = fServerList.find(trunc);
220  if (v!=fServerList.end())
221  {
222  wout << kRed << "Server '" << trunc << "' in list not as it ought to be." << endl;
223  continue;
224  }
225 
226  // Add the new server to the server list
227  fServerList[trunc] = make_pair(CreateSL(trunc), CreateFMT(trunc));
228 
229  wout << " -> " << Time().GetAsStr() << " - " << trunc << "/SERVICE_LIST: Connected." << endl;
230  //wout << "Add : " << server << endl;
231  continue;
232  }
233 
234  // In any other case we just add the entry to the list
235  fServerList[server] = make_pair(CreateSL(server), CreateFMT(server));
236  //wout << "Add 0: " << server << endl;
237  }
238 }
239 
240 // --------------------------------------------------------------------------
241 //
257 {
258  const string str = info.getString();
259  if (str.empty())
260  return;
261 
262  // Get the name of the service
263  string buffer = info.getName();
264 
265  if (buffer.find("SERVICE_DESC")!=buffer.length()-12)
266  {
267  // Get the server name from the service name
268  const string server = buffer.substr(0, buffer.find_first_of('/'));
269 
270  // Initialize the entry with an empty list
271  if (str[0]!='+')
272  fServiceList[server] = vector<string>();
273 
274  // For easy and fast access get the corresponding reference
275  vector<string> &list = fServiceList[server];
276 
277  // Tokenize the stream into lines
278  stringstream stream(str);
279  while (getline(stream, buffer, '\n'))
280  {
281  if (buffer.empty())
282  continue;
283 
284  // Get the type and compare it with fType
285  const string type = buffer.substr(buffer.find_last_of('|')+1);
286  if (type!=fType)
287  continue;
288 
289  // Get format, name and command name
290  const string fmt = buffer.substr(buffer.find_first_of('|')+1, buffer.find_last_of('|')-buffer.find_first_of('|')-1);
291  const string name = buffer.substr(buffer.find_first_of('/')+1, buffer.find_first_of('|')-buffer.find_first_of('/')-1);
292  const string cmd = buffer.substr(0, buffer.find_first_of('|'));
293 
294  // Add name the the list
295  list.push_back(name);
296 
297  // Add format to the list
298  fFormatList[cmd] = fmt;
299  }
300  }
301  else
302  {
303  fDescriptionMap.clear();
304 
305  stringstream stream(str);
306  while (getline(stream, buffer, '\n'))
307  {
308  if (buffer.empty())
309  continue;
310 
311  const vector<Description> v = Description::SplitDescription(buffer);
312 
313  const string svc = v[0].name;
314 
315  fDescriptionMap[svc] = v[0].comment;
316  fDescriptionList[svc] = vector<Description>(v.begin()+1, v.end());
317  }
318  }
319 }
320 
321 // --------------------------------------------------------------------------
322 //
325 //
326 vector<string> ServiceList::GetServerList() const
327 {
328  vector<string> v;
329  for (ServerMap::const_iterator i=fServerList.begin(); i!=fServerList.end(); i++)
330  v.push_back(i->first);
331 
332  return v;
333 }
334 
335 vector<string> ServiceList::GetServiceList(const std::string &server) const
336 {
337  const ServiceMap::const_iterator m = fServiceList.find(server);
338  return m==end() ? vector<string>() : m->second;
339 }
340 
341 vector<string> ServiceList::GetServiceList() const
342 {
343  vector<string> vec;
344  for (ServerMap::const_iterator i=fServerList.begin(); i!=fServerList.end(); i++)
345  {
346  const string server = i->first;
347 
348  const vector<string> v = GetServiceList(server);
349 
350  for (vector<string>::const_iterator s=v.begin(); s<v.end(); s++)
351  vec.push_back(server+"/"+*s);
352  }
353 
354  return vec;
355 }
356 
357 // --------------------------------------------------------------------------
358 //
367 //
368 string ServiceList::GetFormat(const string &service) const
369 {
370  const StringMap::const_iterator i = fFormatList.find(service);
371  return i==fFormatList.end() ? "" : i->second;
372 }
373 
374 // --------------------------------------------------------------------------
375 //
387 //
388 string ServiceList::GetFormat(const string &server, const string &name) const
389 {
390  return GetFormat(server+'/'+name);
391 }
392 
393 // --------------------------------------------------------------------------
394 //
403 //
404 vector<Description> ServiceList::GetDescriptions(const string &service) const
405 {
406  const DescriptionMap::const_iterator i = fDescriptionList.find(service);
407  return i==fDescriptionList.end() ? vector<Description>() : i->second;
408 }
409 
410 // --------------------------------------------------------------------------
411 //
422 //
423 vector<Description> ServiceList::GetDescriptions(const string &server, const string &name) const
424 {
425  return GetDescriptions(server+'/'+name);
426 }
427 
428 // --------------------------------------------------------------------------
429 //
438 //
439 string ServiceList::GetComment(const string &service) const
440 {
441  const StringMap::const_iterator i = fDescriptionMap.find(service);
442  return i==fDescriptionMap.end() ? "" : i->second;
443 }
444 
445 // --------------------------------------------------------------------------
446 //
457 //
458 string ServiceList::GetComment(const string &server, const string &name) const
459 {
460  return GetComment(server+"/"+name);
461 }
462 
463 // --------------------------------------------------------------------------
464 //
472 //
473 bool ServiceList::HasServer(const string &name) const
474 {
475  return fServiceList.find(name)!=end();
476 }
477 
478 // --------------------------------------------------------------------------
479 //
490 //
491 bool ServiceList::HasService(const string &server, const string &service) const
492 {
493  ServiceMap::const_iterator v = fServiceList.find(server);
494  if (v==end())
495  return false;
496 
497  const vector<string> &w = v->second;
498  return find(w.begin(), w.end(), service)!=w.end();
499 }
500 
501 bool ServiceList::HasService(const string &svc) const
502 {
503  const size_t p = svc.find_first_of('/');
504  if (p==string::npos)
505  return false;
506 
507  return HasService(svc.substr(0, p), svc.substr(p+1));
508 }
509 
510 // --------------------------------------------------------------------------
511 //
522 //
523 vector<string>::const_iterator ServiceList::begin(const string &server) const
524 {
525  ServiceMap::const_iterator i = fServiceList.find(server);
526  if (i==end())
527  return vector<string>().end();
528 
529  return i->second.begin();
530 }
531 
532 // --------------------------------------------------------------------------
533 //
544 //
545 vector<string>::const_iterator ServiceList::end(const string &server) const
546 {
547  ServiceMap::const_iterator i = fServiceList.find(server);
548  if (i==end())
549  return vector<string>().end();
550 
551  return i->second.end();
552 }
553 
554 
555 // --------------------------------------------------------------------------
556 //
562 void ServiceList::PrintServerList(ostream &out) const
563 {
564  out << endl << kBold << "ServerList:" << endl;
565 
566  for (ServerMap::const_iterator i=fServerList.begin(); i!=fServerList.end(); i++)
567  {
568  const string &server = i->first;
569  DimInfo *ptr1 = i->second.first;
570  DimInfo *ptr2 = i->second.second;
571 
572  out << " " << server << " " << ptr1->getName() << "|" << ptr2->getName() << endl;
573  }
574  out << endl;
575 }
576 
577 // --------------------------------------------------------------------------
578 //
584 void ServiceList::PrintServiceList(ostream &out) const
585 {
586  out << endl << kBold << "ServiceList:" << endl;
587 
588  for (ServiceMap::const_iterator i=fServiceList.begin(); i!=fServiceList.end(); i++)
589  {
590  const string &server = i->first;
591  const vector<string> &lst = i->second;
592 
593  out << " " << server << endl;
594 
595  for (vector<string>::const_iterator j=lst.begin(); j!=lst.end(); j++)
596  out << " " << *j << " [" << GetFormat(server, *j) << "]" << endl;
597  }
598  out << endl;
599 }
600 
601 // --------------------------------------------------------------------------
602 //
614 //
615 int ServiceList::PrintDescription(std::ostream &out, const string &serv, const string &service) const
616 {
617  int rc = 0;
618  for (ServiceMap::const_iterator i=fServiceList.begin(); i!=fServiceList.end(); i++)
619  {
620  const string &server = i->first;
621 
622  if (!serv.empty() && server!=serv)
623  continue;
624 
625  out << kRed << "----- " << server << " -----" << endl;
626 
627  const vector<string> &lst = i->second;
628  for (vector<string>::const_iterator s=lst.begin(); s!=lst.end(); s++)
629  {
630  if (!service.empty() && *s!=service)
631  continue;
632 
633  rc++;
634 
635  out << " " << *s;
636 
637  const string fmt = GetFormat(server, *s);
638  if (!fmt.empty())
639  out << '[' << fmt << ']';
640 
641  const string svc = server + '/' + *s;
642 
643  const DescriptionMap::const_iterator v = fDescriptionList.find(svc);
644  if (v==fDescriptionList.end())
645  {
646  out << endl;
647  continue;
648  }
649 
650  for (vector<Description>::const_iterator j=v->second.begin();
651  j!=v->second.end(); j++)
652  out << " <" << j->name << ">";
653  out << endl;
654 
655  const StringMap::const_iterator d = fDescriptionMap.find(svc);
656  if (d!=fDescriptionMap.end() && !d->second.empty())
657  out << " " << d->second << endl;
658 
659  for (vector<Description>::const_iterator j=v->second.begin();
660  j!=v->second.end(); j++)
661  {
662  out << " " << kGreen << j->name;
663  if (!j->comment.empty())
664  out << kReset << ": " << kBlue << j->comment;
665  if (!j->unit.empty())
666  out << kYellow << " [" << j->unit << "]";
667  out << endl;
668  }
669  }
670  out << endl;
671  }
672 
673  return rc;
674 }
675 
676 // --------------------------------------------------------------------------
677 //
685 {
686  DimCurrentInfo info1("DIS_DNS/SERVER_LIST", const_cast<char*>(""));
687 
688  stringstream stream(info1.getString());
689 
690  string buffer;
691  while (getline(stream, buffer, '|'))
692  {
693  const string server = buffer.substr(0, buffer.find_first_of('@'));
694  if (server.empty())
695  continue;
696 
697  out << kBold << " " << server << endl;
698 
699  DimCurrentInfo info2((server+"/SERVICE_LIST").c_str(), const_cast<char*>(""));
700 
701  string buffer2;
702 
703  stringstream stream2(info2.getString());
704  while (getline(stream2, buffer2, '\n'))
705  {
706  if (buffer2.empty())
707  continue;
708 
709  out << " " << buffer2 << endl;
710  }
711  }
712 }
713 
714 // --------------------------------------------------------------------------
715 //
732 bool ServiceList::SendDimCommand(ostream &lout, const string &server, const string &str) const
733 {
734  // Find the delimiter between the command name and the data
735  size_t p0 = str.find_first_of(' ');
736  if (p0==string::npos)
737  p0 = str.length();
738 
739  // Get just the command name separated from the data
740  const string name = str.substr(0, p0);
741 
742  // Compile the command which will be sent to the state-machine
743  const string cmd = server + '/' + name;
744 
745  if (!HasService(server, name))
746  {
747  lout << kRed << "Unkown command '" << cmd << "'" << endl;
748  return false;
749  }
750 
751  // Get the format of the event data
752  const string fmt = GetFormat(cmd);
753 
754  // Convert the user entered data according to the format string
755  // into a data block which will be attached to the event
756  const Converter conv(lout, fmt, false);
757  if (!conv)
758  {
759  lout << kRed << "Couldn't properly parse the format... ignored." << endl;
760  return false;
761  }
762 
763  try
764  {
765  lout << kBlue << cmd;
766  const vector<char> v = conv.GetVector(str.substr(p0));
767  lout << endl;
768 
769  const int rc = DimClient::sendCommand(cmd.c_str(), (void*)v.data(), v.size());
770  if (rc)
771  lout << kGreen << "Command " << cmd << " emitted successfully to DimClient." << endl;
772  else
773  lout << kRed << "ERROR - Sending command " << cmd << " failed." << endl;
774  }
775  catch (const std::runtime_error &e)
776  {
777  lout << endl << kRed << e.what() << endl;
778  return false;
779  }
780 
781  return true;
782 }
char * getString()
Definition: dic.hxx:108
static int sendCommand(const char *name, int data)
Definition: diccpp.cxx:1098
ServerMap fServerList
A filter for the type of the services to be collected, e.g. CMD.
Definition: ServiceList.h:29
void ProcessServerList()
Definition: ServiceList.cc:149
virtual void infoHandler()=0
ServiceMap::const_iterator begin() const
Definition: ServiceList.h:62
int i
Definition: db_dim_client.c:21
Set color Green.
Definition: WindowLog.h:18
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
char str[80]
Definition: test_client.c:7
Set color Yellow.
Definition: WindowLog.h:19
ServiceList(const char *type, std::ostream &out=std::cout)
Definition: ServiceList.cc:60
bool SendDimCommand(std::ostream &lout, const std::string &server, const std::string &str) const
Definition: ServiceList.cc:732
Set color Red.
Definition: WindowLog.h:17
StringMap fFormatList
A map storing server names and vector with all their available commands.
Definition: ServiceList.h:31
std::string GetComment(const std::string &server, const std::string &name) const
Definition: ServiceList.cc:458
STL namespace.
ServiceMap fServiceList
A map storing server names and a DimInfo for their SERVICE_LIST.
Definition: ServiceList.h:30
void PrintServiceList() const
Definition: ServiceList.h:81
DimInfo fDimServers
stream for redirection of the output
Definition: ServiceList.h:25
Definition: dic.hxx:31
void ProcessServiceList(DimInfo &info)
Definition: ServiceList.cc:256
std::vector< std::string > GetServiceList() const
Definition: ServiceList.cc:341
bool HasService(const std::string &server, const std::string &service) const
Definition: ServiceList.cc:491
ServiceMap::const_iterator end() const
Definition: ServiceList.h:63
DimInfo * CreateFMT(const std::string &str) const
Definition: ServiceList.h:40
std::ostream & wout
Definition: ServiceList.h:23
DimInfo * CreateSL(const std::string &str) const
Definition: ServiceList.h:39
std::vector< std::string > GetServerList() const
Definition: ServiceList.cc:326
bool HasServer(const std::string &name) const
Definition: ServiceList.cc:473
Definition: dis.c:69
int type
uint16_t fType
Type of the data to be received after the header.
Definition: HeadersFTM.h:187
int PrintDescription(std::ostream &out, const std::string &serv="", const std::string &svc="") const
Definition: ServiceList.cc:615
std::string GetFormat(const std::string &server, const std::string &name) const
Definition: ServiceList.cc:388
const std::string fType
A DimInfo to retrieve the SERVER_LIST from teh DNS server.
Definition: ServiceList.h:27
Set color Blue.
Definition: WindowLog.h:20
std::vector< Description > GetDescriptions(const std::string &server, const std::string &name) const
Definition: ServiceList.cc:423
DescriptionMap fDescriptionList
A map storing all descriptions for commands and services.
Definition: ServiceList.h:33
DimInfo * CreateDimInfo(const std::string &str, const std::string &svc) const
A callback to signal updates.
Definition: ServiceList.cc:132
static std::vector< Description > SplitDescription(const std::string &buffer)
Definition: Description.cc:82
int buffer[BUFFSIZE]
Definition: db_dim_client.c:14
DimInfo * itsService
Definition: dic.hxx:25
void infoHandler()
Definition: ServiceList.cc:105
void PrintServerList() const
Definition: ServiceList.h:80
~ServiceList()
Delete the allocated memory from fServerList.
Definition: ServiceList.cc:86
if(extraDns) new Dns
DimInfo * getInfo()
Definition: dic.hxx:26
DimInfoHandler * fHandler
A map storing all descriptions for arguments of command and services.
Definition: ServiceList.h:35
std::string GetAsStr(const char *fmt="%Y-%m-%d %H:%M:%S") const
Definition: Time.cc:240
A compiler for the DIM data format string.
Definition: Converter.h:16
Reset all attributes.
Definition: WindowLog.h:29
StringMap fDescriptionMap
A map storing all commands and their format strings.
Definition: ServiceList.h:32
char * getString()
Definition: dic.hxx:339
void DumpServiceList() const
Definition: ServiceList.h:85
Set attribute Bold.
Definition: WindowLog.h:36
std::vector< char > GetVector(const void *d, size_t size) const
Definition: Converter.cc:724
char * getName()
Definition: dic.hxx:101