Belle II Software  release-08-01-10
NSMCallback.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include "daq/slc/nsm/NSMCallback.h"
9 
10 #include "daq/slc/system/LogFile.h"
11 
12 #include "daq/slc/nsm/NSMCommunicator.h"
13 #include "daq/slc/nsm/NSMHandlerException.h"
14 
15 #include "daq/slc/version/Version.h"
16 
17 #include <cstdlib>
18 #include <iostream>
19 #include <sstream>
20 #include <cstdarg>
21 
22 using namespace Belle2;
23 
24 NSMCallback::NSMCallback(const int timeout)
25  : AbstractNSMCallback(timeout)
26 {
27  reg(NSMCommand::OK);
28  reg(NSMCommand::ERROR);
29  reg(NSMCommand::LOG);
30  reg(NSMCommand::VGET);
31  reg(NSMCommand::VSET);
32  reg(NSMCommand::VREPLY);
33  reg(NSMCommand::VLISTGET);
34  reg(NSMCommand::VLISTSET);
35 
36  addDefaultHandlers();
37 }
38 
39 
40 int NSMCallback::reset()
41 {
42  int revision = Callback::reset();
43 
44  addDefaultHandlers();
45 
46  return revision;
47 }
48 
49 int NSMCallback::addDefaultHandlers()
50 {
51  return add(new NSMVHandlerText("version", true, false, DAQ_SLC_VERSION::DAQ_SLC_VERSION), false, true);
52 }
53 
54 void NSMCallback::addNode(const NSMNode& node)
55 {
56  std::string name = node.getName();
57  if (m_nodes.find(name) == m_nodes.end()) {
58  m_nodes.insert(NSMNodeMap::value_type(name, node));
59  }
60 }
61 
62 void NSMCallback::reply(const NSMMessage& msg)
63 {
64  NSMMessage msg_out = msg;
65  for (NSMNodeMap::iterator it = m_nodes.begin();
66  it != m_nodes.end();) {
67  NSMNode& node(it->second);
68  msg_out.setNodeName(node.getName());
69  if (NSMCommunicator::send(msg_out)) {
70  ++it;
71  } else {
72  m_nodes.erase(it++);
73  }
74  }
75 }
76 
77 void NSMCallback::log(LogFile::Priority pri, const char* format, ...)
78 {
79  va_list ap;
80  char ss[1024 * 10];
81  va_start(ap, format);
82  vsnprintf(ss, sizeof(ss), format, ap);
83  va_end(ap);
84  log(pri, std::string(ss));
85 }
86 
87 void NSMCallback::log(LogFile::Priority pri, const std::string& msg)
88 {
89  LogFile::put(pri, msg);
90  try {
91  if (getLogNode().getName().size() > 0) {
92  NSMCommunicator::send(NSMMessage(getLogNode().getName(),
93  DAQLogMessage(getNode().getName(),
94  pri, getCategory(), msg)));
95  }
96  } catch (const NSMHandlerException& e) {
97  LogFile::error(e.what());
98  }
99 }
100 
101 bool NSMCallback::perform(NSMCommunicator& com)
102 {
103  const NSMMessage& msg(com.getMessage());
104  const NSMCommand cmd = msg.getRequestName();
105  if (cmd == NSMCommand::OK || cmd == NSMCommand::ERROR ||
106  cmd == NSMCommand::FATAL) {
107  if (msg.getLength() > 0) {
108  if (cmd == NSMCommand::OK) {
109  ok(msg.getNodeName(), msg.getData());
110  } else if (cmd == NSMCommand::ERROR) {
111  error(msg.getNodeName(), msg.getData());
112  } else if (cmd == NSMCommand::FATAL) {
113  fatal(msg.getNodeName(), msg.getData());
114  }
115  }
116  return true;
117  } else if (cmd == NSMCommand::LOG) {
118  int id = com.getNodeIdByName(msg.getNodeName());
119  DAQLogMessage lmsg;
120  lmsg.setId(id);
121  lmsg.setNodeName(msg.getNodeName());
122  if (msg.getNParams() > 0) {
123  lmsg.setPriority((LogFile::Priority)msg.getParam(0));
124  }
125  if (msg.getNParams() > 1) lmsg.setDate(msg.getParam(1));
126  if (msg.getNParams() > 2) lmsg.setCategory(msg.getParam(2));
127  lmsg.setMessage(msg.getLength() > 0 ? msg.getData() : "");
128  logset(lmsg);
129  return true;
130  } else if (cmd == NSMCommand::VGET) {
131  if (msg.getLength() > 0) {
132  vget(msg.getNodeName(), msg.getData());
133  }
134  return true;
135  } else if (cmd == NSMCommand::VSET) {
136  if (msg.getLength() > 0) {
137  NSMVar var;
138  readVar(msg, var);
139  vset(com, var);
140  }
141  return true;
142  } else if (cmd == NSMCommand::VREPLY) {
143  vreply(com, msg.getData(), msg.getParam(0));
144  return true;
145  } else if (cmd == NSMCommand::VLISTGET) {
146  vlistget(com);
147  return true;
148  } else if (cmd == NSMCommand::VLISTSET) {
149  vlistset(com);
150  return true;
151  }
152  return false;
153 }
154 
155 void NSMCallback::notify(const NSMVar& var)
156 {
157  std::string vname = var.getName();
158  NSMVar var_out = var;
159  if (var_out.getNode().size() == 0) {
160  var_out.setNode(getNode().getName());
161  }
162 
163  if (m_node_v_m.find(vname) != m_node_v_m.end()) {
164  try {
165  NSMNodeMap& node_v(m_node_v_m[vname]);
166  for (NSMNodeMap::iterator inode = node_v.begin();
167  inode != node_v.end();) {
168  NSMNode& node(inode->second);
169  if (NSMCommunicator::send(NSMMessage(node, var_out))) {
170  ++inode;
171  } else {
172  node_v.erase(inode++);
173  }
174  }
175  } catch (const IOException& e) {
176  LogFile::error(e.what());
177  }
178  }
179 }
180 
181 void NSMCallback::vget(const std::string& nodename, const std::string& vname)
182 {
183  NSMNode node(nodename);
184  NSMVar var(vname);
185  try {
186  NSMVHandler* handler_p = getHandler_p(nodename, vname);
187  if (handler_p) {
188  NSMVHandler& handler(*handler_p);
189  handler.handleGet(var);
190  var.setNode(getNode().getName());
191  var.setName(vname);
192  //var.setId(i + 1);
193  var.setDate(Date());
194  NSMCommunicator::send(NSMMessage(node, var));
195  if (m_node_v_m.find(vname) == m_node_v_m.end()) {
196  m_node_v_m.insert(NSMNodeMapMap::value_type(vname, NSMNodeMap()));
197  }
198  NSMNodeMap& node_v(m_node_v_m[vname]);
199  if (node_v.find(nodename) == node_v.end()) {
200  node_v.insert(NSMNodeMap::value_type(nodename, NSMNode(nodename)));
201  std::string filename = ("/tmp/nsmvget." + StringUtil::tolower(getNode().getName()));
202  std::ofstream fout(filename.c_str(), std::ios::app);
203  fout << nodename << " " << vname << std::endl;
204  }
205  }
206  } catch (const NSMHandlerException& e) {
207  LogFile::error(e.what());
208  }
209 }
210 
211 void NSMCallback::vset(NSMCommunicator& com, const NSMVar& var)
212 {
213  try {
214  NSMMessage msg(com.getMessage());
215  NSMVHandler* handler_p = getHandler_p(var.getNode(), var.getName());
216  if (handler_p) {
217  NSMVHandler& handler(*handler_p);
218  if (var.getName() == handler.getName() &&
219  (var.getNode() == handler.getNode() ||
220  (var.getNode().size() == 0 && handler.getNode() == getNode().getName()) ||
221  (handler.getNode().size() == 0 && var.getNode() == getNode().getName())) &&
222  handler.useSet()) {
223  NSMNode node(msg.getNodeName());
224  bool result = false;
225  if ((result = handler.handleSet(var)) &&
226  (var.getNode().size() == 0 || var.getNode() == getNode().getName())) {
227  notify(var);
228  }
229  if (var.getNode().size() == 0) {
230  NSMCommunicator::send(NSMMessage(node, NSMCommand::VREPLY,
231  result, var.getName()));
232  }
233  }
234  }
235  } catch (const NSMHandlerException& e) {
236  LogFile::error(e.what());
237  }
238 }
239 
240 void NSMCallback::vlistget(NSMCommunicator& com)
241 {
242  std::stringstream ss;
243  int i = 0;
244  int count = 0;
245  for (NSMVHandlerList::iterator it = m_handler.begin();
246  it != m_handler.end(); ++it) {
247  NSMVHandler& handler(*it->second);
248  if (handler.getNode().size() == 0) {
249  ss << handler.getName() << ":"
250  << handler.get().getTypeLabel() << ":"
251  << (int)handler.useGet() << ":"
252  << (int)handler.useSet() << ":"
253  << i << "\n";
254  count++;
255  }
256  i++;
257  }
258  std::string nodename = com.getMessage().getNodeName();
259  NSMNode node(nodename);
260  try {
261  NSMCommunicator::send(NSMMessage(node, NSMCommand::VLISTSET,
262  count, ss.str()));
263  } catch (const NSMHandlerException& e) {
264  LogFile::error(e.what());
265  }
266 }
267 
268 struct vlistentry_t {
269  std::string name;
270  int id;
271  std::string type;
272  bool useGet;
273  bool useSet;
274 };
275 
276 void NSMCallback::vlistset(NSMCommunicator& com)
277 {
278  std::string data = com.getMessage().getData();
279  StringList s = StringUtil::split(data, '\n');
280  std::vector<vlistentry_t> vlist;
281  size_t length = 0;
282  for (size_t i = 0; i < s.size(); i++) {
283  StringList ss = StringUtil::split(s[i], ':');
284  if (ss.size() > 4) {
285  vlistentry_t en = { ss[0], atoi(ss[4].c_str()),
286  ss[1], ss[2] == "1", ss[3] == "1"
287  };
288  vlist.push_back(en);
289  if (length < ss[0].size()) length = ss[0].size();
290  }
291  }
292  for (size_t i = 0; i < vlist.size(); i++) {
293  vlistentry_t& en(vlist[i]);
294  std::cout << StringUtil::form(StringUtil::form("%%-%ds ", length).c_str(), en.name.c_str())
295  << " : " << en.type << " "
296  << (en.useGet ? "get " : "")
297  << (en.useSet ? "set " : "") << std::endl;
298  }
299 }
300 
301 void NSMCallback::alloc_open(NSMCommunicator& com)
302 {
303  try {
304  if (!m_data.isAvailable() && m_data.getName().size() > 0 &&
305  m_data.getFormat().size() > 0 && m_data.getRevision() > 0) {
306  m_data.allocate(com);
307  }
308  } catch (const NSMHandlerException& e) {
309  LogFile::warning(e.what());
310  }
311  for (NSMDataMap::iterator it = m_datas.begin();
312  it != m_datas.end(); ++it) {
313  NSMData& data(it->second);
314  try {
315  if (!data.isAvailable() && data.getName().size() > 0 &&
316  data.getFormat().size() > 0) {
317  data.open(com);
318  }
319  } catch (const NSMHandlerException& e) {
320  }
321  }
322 }
323 
TString getName(const TObject *obj)
human-readable name (e.g.
Definition: ObjectInfo.cc:45
Abstract base class for different kinds of events.