Jpp  master_rocky
the software that should make you happy
JClient.hh
Go to the documentation of this file.
1 #ifndef __JRUNCONTROL__JCLIENT__
2 #define __JRUNCONTROL__JCLIENT__
3 
4 #include <string>
5 #include <iostream>
6 #include <sstream>
7 
8 #include "JLang/JException.hh"
9 #include "JLang/JString.hh"
11 #include "JDAQ/JDAQTags.hh"
12 #include "JRuncontrol/JEvent_t.hh"
14 #include "JNet/JPrefix.hh"
15 #include "JSystem/JShell.hh"
16 
17 
18 /**
19  * \author mdejong
20  */
21 
22 namespace KM3NETDAQ {
23 
24 
25  /**
26  * Client data structure.
27  */
28  class JClient {
29  public:
30 
31 
32  static std::string SERVER; //!< host name of message server
33  static std::string LOGGER; //!< host name of message logger
34 
35 
36  /**
37  * Client modi.
38  */
39  enum JMode { UNKNOWN = -1, SLEEP = 0, ACTIVE, IGNORE = -2, ILLEGAL = -3 };
40 
41 
42  /**
43  * Default constructor.
44  */
45  JClient() :
46  name (),
47  hostname (),
48  start_command(),
49  mode(UNKNOWN),
50  born(0),
51  died(0),
52  is_alive(false),
53  state_name("?"),
54  event_name("?"),
55  event_info()
56  {}
57 
58 
59  /**
60  * Constructor.
61  *
62  * \param __name name of client
63  * \param __hostname host name
64  * \param __start_command start command
65  */
66  JClient(const std::string& __name,
67  const std::string& __hostname,
68  const std::string& __start_command = "") :
69  name (__name),
70  hostname (__hostname),
71  start_command(__start_command),
72  mode(UNKNOWN),
73  born(0),
74  died(0),
75  is_alive(false),
76  state_name("?"),
77  event_name("?"),
78  event_info()
79  {
80  configure();
81  }
82 
83 
84  /**
85  * Start process.
86  * The start command is issued on the (remote) host.
87  */
88  void start()
89  {
90  using namespace std;
91  using namespace JPP;
92 
93  if (start_command != "") {
94 
95  JShell& shell = JShell::getInstance();
96 
97  shell << start_command << endl;
98  shell.flush(cout);
99  }
100  }
101 
102 
103  /**
104  * Stop process.
105  * A kill command is issued on the (remote) host.
106  * To determine the PID for the kill command, the start command is compared to
107  * the output of a ps command on the (remote) host.
108  *
109  * \param signal signal
110  */
111  void stop(const int signal = -9)
112  {
113  using namespace std;
114  using namespace JPP;
115 
116  if (start_command != "") {
117 
118  const string header = "__header___";
119  const string trailer = "__trailer__";
120 
121  ostringstream os;
122 
123  os << "ssh " << hostname << ' '
124  << "\""
125  << "echo" << ' ' << header << ";"
126  << "ps hax -o '%p %a'" << ";"
127  << "echo" << ' ' << trailer
128  << "\"";
129 
130  JShell& shell = JShell::getInstance();
131 
132  shell << os.str() << endl;
133 
134  os.str("");
135 
136  string buffer;
137 
138  while (getline(shell, buffer) && buffer.find(header) == string::npos) {}
139 
140  istringstream is;
141 
142  while (getline(shell, buffer) && buffer.find(trailer) == string::npos) {
143 
144  is.clear();
145  is.str(buffer);
146 
147  int pid;
148 
149  if (is >> pid && getline(is >> ws, buffer)) {
150  if (start_command.find(buffer) != string::npos) {
151  os << "ssh " << hostname << ' '
152  << "\""
153  << "kill " << signal << " " << pid << " </dev/null >&/dev/null"
154  << "\"";
155  }
156  }
157  }
158 
159  shell.flush();
160 
161  if (os.str() != "") {
162  shell << os.str() << endl;
163  shell.flush();
164  }
165  }
166  }
167 
168 
169  /**
170  * Get name of run control client.
171  *
172  * \return name
173  */
174  const std::string& getName() const
175  {
176  return name;
177  }
178 
179 
180  /**
181  * Get host name of run control client.
182  *
183  * \return host name
184  */
185  const std::string& getHostname() const
186  {
187  return hostname;
188  }
189 
190 
191  /**
192  * Get full name of run control client.
193  *
194  * \return full name
195  */
196  const std::string& getFullName() const
197  {
198  return full_name;
199  }
200 
201 
202  /**
203  * Get start command of run control client.
204  *
205  * \return name
206  */
207  const std::string& getStartCommand() const
208  {
209  return start_command;
210  }
211 
212 
213  /**
214  * Check sleep mode.
215  *
216  * \return true if sleep; else false
217  */
218  bool isSleep() const
219  {
220  return mode == SLEEP;
221  }
222 
223 
224  /**
225  * Check active mode.
226  *
227  * \return true if active; else false
228  */
229  bool isActive() const
230  {
231  return mode == ACTIVE;
232  }
233 
234 
235  /**
236  * Check ignore mode.
237  *
238  * \return true if ignore; else false
239  */
240  bool isIgnore() const
241  {
242  return mode == IGNORE;
243  }
244 
245 
246  /**
247  * Check illegal mode.
248  *
249  * \return true if illegal; else false
250  */
251  bool isIllegal() const
252  {
253  return mode == ILLEGAL;
254  }
255 
256 
257  /**
258  * Update client.
259  * The client parameters are updated according to the ControlHost tag and message.
260  *
261  * \param tag tag
262  * \param buffer message
263  * \return true if OK; else false
264  */
265  bool update(const JNET::JTag& tag, const std::string& buffer)
266  {
267  using namespace std;
269 
270  if (tag == JNET::DISPTAG_Born) {
271 
272  this->is_alive = true;
273  this->born += 1;
274 
275  return true;
276 
277  } else if (tag == JNET::DISPTAG_Died) {
278 
279  this->is_alive = false;
280  this->died += 1;
281 
282  return true;
283 
284  } else if (tag == RC_REPLY) {
285 
286  string key;
287  string ip;
288  string name;
289  JEvent_t event;
290  string state;
291 
292  istringstream is(buffer);
293 
294  const locale loc(is.getloc(), new JWhiteSpacesFacet(is.getloc(), TOKEN_DELIMETER));
295 
296  is.imbue(loc);
297 
298  if (is >> key >> ip >> name >> event >> state && key == RUN_CONTROL_CLIENT) {
299 
300  this->event_name = event.getName();
301  this->event_info = event.getInfo();
302  this->state_name = state;
303 
304  return true;
305  }
306  }
307 
308  return false;
309  }
310 
311 
312  /**
313  * Get name of current state.
314  *
315  * \return state name
316  */
317  const std::string& getStatename() const
318  {
319  return state_name;
320  }
321 
322 
323  /**
324  * Get name of last event.
325  *
326  * \return event name
327  */
328  const std::string& getEventname() const
329  {
330  return event_name;
331  }
332 
333 
334  /**
335  * Get event information.
336  *
337  * \return event information
338  */
339  const std::string& getEventInfo() const
340  {
341  return event_info;
342  }
343 
344 
345  /**
346  * Get alive status.
347  *
348  * \return true if alive; else false
349  */
350  bool getAlive() const
351  {
352  return is_alive;
353  }
354 
355 
356  /**
357  * Set alive status.
358  *
359  * \param alive alive
360  */
361  void setAlive(const bool alive)
362  {
363  is_alive = alive;
364  }
365 
366 
367  /**
368  * Get mode.
369  *
370  * \return mode
371  */
372  JMode getMode() const
373  {
374  return mode;
375  }
376 
377 
378  /**
379  * Set mode.
380  *
381  * \param mode mode
382  */
383  void setMode(const JMode mode)
384  {
385  this->mode = mode;
386  }
387 
388 
389  /**
390  * Get born count.
391  *
392  * \return number of times born
393  */
394  int getBorn() const
395  {
396  return born;
397  }
398 
399 
400  /**
401  * Get died count.
402  *
403  * \return number of times died
404  */
405  int getDied() const
406  {
407  return died;
408  }
409 
410 
411  /**
412  * Read client from input.
413  *
414  * \param in istream
415  * \param client client
416  * \return istream
417  */
418  friend inline std::istream& operator>>(std::istream& in, JClient& client)
419  {
420  in >> client.name;
421  in >> client.hostname;
422 
423  if (in) {
424 
425  getline(in >> std::ws, client.start_command);
426 
427  in.clear(); // clear error state of input stream if no start command is available.
428 
429  client.configure();
430  }
431 
432  return in;
433  }
434 
435 
436  /**
437  * Write client to output.
438  *
439  * \param out ostream
440  * \param client client
441  * \return ostream
442  */
443  friend inline std::ostream& operator<<(std::ostream& out, const JClient& client)
444  {
445  out << client.name;
446  out << ' ';
447  out << client.hostname;
448  out << ' ';
449  out << client.start_command;
450 
451  return out;
452  }
453 
454 
455  protected:
456  /**
457  * Configure client parameters.
458  * In this, the following tokens in the start command are substituted:
459  * $HOST$ by <host name>;
460  * $NAME$ by <process name>;
461  * $SERVER$ by JClient::SERVER;
462  * $LOGGER$ by JClient::LOGGER;
463  * $ARGS$ by part following last '/' in <process name>;
464  */
465  void configure()
466  {
467  using std::string;
468 
469  full_name = KM3NETDAQ::getFullName(hostname, name);
470 
471  start_command = start_command.trim();
472  start_command = start_command.replace(" ", " ");
473 
474  start_command.replace("$HOST$", hostname);
475  start_command.replace("$NAME$", name);
476  start_command.replace("$SERVER$", SERVER);
477  start_command.replace("$LOGGER$", LOGGER);
478 
479  string::size_type pos = name.find_last_of(CLIENTNAME_DELIMETER);
480 
481  if (pos != string::npos) {
482  start_command.replace("$ARGS$", name.substr(pos + 1));
483  }
484  }
485 
486 
487  std::string name;
488  std::string hostname;
490  std::string full_name;
492  int born;
493  int died;
494  bool is_alive;
495  std::string state_name;
496  std::string event_name;
497  std::string event_info;
498  };
499 }
500 
501 #endif
Fixed parameters and ControlHost tags for KM3NeT DAQ.
Exceptions.
Shell interaction via I/O streams.
virtual void clear()
Clear status of reader.
Wrapper class around STL string class.
Definition: JString.hh:29
Auxiliary class to specify white space character(s) in currect locale.
ControlHost client manager.
Definition: JLigier.cc:245
JSocketNonblockingWriter out
writer for outgoing messages
Definition: JLigier.cc:462
JSocketInputChannel_t in
reader for incoming messages
Definition: JLigier.cc:461
ControlHost tag.
Definition: JTag.hh:38
The JShell clas can be used to interact with the shell via I/O streams.
Definition: JShell.hh:36
static JShell & getInstance()
Get reference to unique instance of this class object.
Definition: JShell.hh:76
JShell & flush(std::ostream &out=null)
Extracts characters from this shell and flush them to the given output stream until the prompt is rea...
Definition: JShell.hh:184
std::string state_name
Definition: JClient.hh:495
const std::string & getHostname() const
Get host name of run control client.
Definition: JClient.hh:185
int getBorn() const
Get born count.
Definition: JClient.hh:394
std::string hostname
Definition: JClient.hh:488
friend std::ostream & operator<<(std::ostream &out, const JClient &client)
Write client to output.
Definition: JClient.hh:443
friend std::istream & operator>>(std::istream &in, JClient &client)
Read client from input.
Definition: JClient.hh:418
const std::string & getEventname() const
Get name of last event.
Definition: JClient.hh:328
bool isSleep() const
Check sleep mode.
Definition: JClient.hh:218
void setMode(const JMode mode)
Set mode.
Definition: JClient.hh:383
JMode
Client modi.
Definition: JClient.hh:39
bool isActive() const
Check active mode.
Definition: JClient.hh:229
const std::string & getEventInfo() const
Get event information.
Definition: JClient.hh:339
JLANG::JString start_command
Definition: JClient.hh:489
const std::string & getStatename() const
Get name of current state.
Definition: JClient.hh:317
void start()
Start process.
Definition: JClient.hh:88
const std::string & getFullName() const
Get full name of run control client.
Definition: JClient.hh:196
const std::string & getName() const
Get name of run control client.
Definition: JClient.hh:174
std::string name
Definition: JClient.hh:487
const std::string & getStartCommand() const
Get start command of run control client.
Definition: JClient.hh:207
bool isIgnore() const
Check ignore mode.
Definition: JClient.hh:240
JMode getMode() const
Get mode.
Definition: JClient.hh:372
JClient(const std::string &__name, const std::string &__hostname, const std::string &__start_command="")
Constructor.
Definition: JClient.hh:66
static std::string SERVER
host name of message server
Definition: JClient.hh:32
bool getAlive() const
Get alive status.
Definition: JClient.hh:350
bool update(const JNET::JTag &tag, const std::string &buffer)
Update client.
Definition: JClient.hh:265
std::string full_name
Definition: JClient.hh:490
std::string event_name
Definition: JClient.hh:496
static std::string LOGGER
host name of message logger
Definition: JClient.hh:33
JClient()
Default constructor.
Definition: JClient.hh:45
void stop(const int signal=-9)
Stop process.
Definition: JClient.hh:111
int getDied() const
Get died count.
Definition: JClient.hh:405
void configure()
Configure client parameters.
Definition: JClient.hh:465
std::string event_info
Definition: JClient.hh:497
bool isIllegal() const
Check illegal mode.
Definition: JClient.hh:251
void setAlive(const bool alive)
Set alive status.
Definition: JClient.hh:361
char * loc(char *orig)
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
static const JTag DISPTAG_Born("Born")
static const JTag DISPTAG_Died("Died")
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
void configure(const T &value, const JAbstractCollection< JAbscissa_t > &bounds, JBool< false > option)
Configuration of value.
KM3NeT DAQ data structures and auxiliaries.
Definition: DataQueue.cc:39
static const JNET::JTag RC_REPLY
Definition: JDAQTags.hh:67
std::string getFullName(const std::string &hostname, const std::string &name)
Get full name of run control client.
static const std::string RUN_CONTROL_CLIENT
Definition: JDAQTags.hh:44
static const std::string TOKEN_DELIMETER
Definition: JDAQTags.hh:58
static const std::string CLIENTNAME_DELIMETER
Definition: JDAQTags.hh:59
Definition: JSTDTypes.hh:14
Auxiliary class for handling event name and optional static information.
Definition: JEvent_t.hh:23