LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
Event.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008-2016 AURA/LSST.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <https://www.lsstcorp.org/LegalNotices/>.
23  */
24 
34 #include "boost/property_tree/ptree.hpp"
35 #include "boost/property_tree/json_parser.hpp"
36 #include "boost/foreach.hpp"
37 
38 #include "lsst/ctrl/events/Event.h"
40 
41 #include "lsst/daf/base/DateTime.h"
43 #include "lsst/pex/exceptions.h"
45 
46 #include "activemq/core/ActiveMQConnectionFactory.h"
47 
48 namespace pexExceptions = lsst::pex::exceptions;
49 namespace dafBase = lsst::daf::base;
50 
51 
52 using namespace std;
53 using std::numeric_limits;
54 
55 namespace lsst {
56 namespace ctrl {
57 namespace events {
58 
59 
60 const std::string Event::TYPE = "TYPE";
61 const std::string Event::EVENTTIME = "EVENTTIME";
62 const std::string Event::RUNID = "RUNID";
63 const std::string Event::STATUS = "STATUS";
64 const std::string Event::TOPIC = "TOPIC";
65 const std::string Event::QUEUE = "QUEUE";
66 const std::string Event::PUBTIME = "PUBTIME";
67 
68 const std::string Event::UNINITIALIZED = "uninitialized";
69 
70 Event::Event() {
71  _init();
72 }
73 
74 void Event::_init() {
75  _keywords.insert(TYPE);
76  _keywords.insert(EVENTTIME);
77  _keywords.insert(STATUS);
78  _keywords.insert(TOPIC);
79  _keywords.insert(PUBTIME);
80  _psp = PTR(PropertySet)(new PropertySet);
81 }
82 
83 Event::Event(cms::TextMessage *msg) {
84 
85  vector<std::string>names = msg->getPropertyNames();
86 
87  _psp = processTextMessage(msg);
88 
89  for (std::string name : names) {
90  _keywords.insert(name);
91  }
92 
93  _psp->set(EVENTTIME, msg->getCMSTimestamp());
94 
95  for (std::string n : names) {
96  //std::string const& name = *n;
97  std::string const& name = n;
98  cms::Message::ValueType vType = msg->getPropertyValueType(name);
99  switch(vType) {
100  case cms::Message::NULL_TYPE:
101  _psp->set(name, NULL);
102  break;
103  case cms::Message::BOOLEAN_TYPE:
104  _psp->set(name, msg->getBooleanProperty(name));
105  break;
106  case cms::Message::BYTE_TYPE:
107  case cms::Message::CHAR_TYPE:
108  _psp->set(name, msg->getByteProperty(name));
109  break;
110  case cms::Message::SHORT_TYPE:
111  _psp->set(name, msg->getShortProperty(name));
112  break;
113  case cms::Message::INTEGER_TYPE:
114  _psp->set(name, msg->getIntProperty(name));
115  break;
116  case cms::Message::LONG_TYPE:
117  _psp->set(name, msg->getLongProperty(name));
118  break;
119  case cms::Message::DOUBLE_TYPE:
120  _psp->set(name, msg->getDoubleProperty(name));
121  break;
122  case cms::Message::FLOAT_TYPE:
123  _psp->set(name, msg->getFloatProperty(name));
124  break;
125  case cms::Message::STRING_TYPE:
126  _psp->set(name, msg->getStringProperty(name));
127  break;
128  case cms::Message::BYTE_ARRAY_TYPE:
129  case cms::Message::UNKNOWN_TYPE:
130  default:
131  std::string msg("Data type represented by "+name+" is not permitted supported");
132  throw LSST_EXCEPT(pexExceptions::RuntimeError, msg);
133  break;
134  }
135  }
136 }
137 
138 vector<std::string> Event::getFilterablePropertyNames() {
139  vector<std::string> _names;
140  for (std::string keyIterator : _keywords) {
141  _names.push_back(keyIterator);
142  }
143  return _names;
144 }
145 
146 vector<std::string> Event::getCustomPropertyNames() {
147  vector<std::string> names = _psp->names();
148 
149  vector<std::string>::iterator nameIterator;
150  set<std::string>::iterator keyIterator;
151 
152  for (nameIterator = names.begin(); nameIterator != names.end();) {
153  keyIterator = _keywords.find(*nameIterator);
154  if (keyIterator == _keywords.end())
155  nameIterator++;
156  else
157  names.erase(nameIterator);
158  }
159  return names;
160 }
161 
162 Event::Event(PropertySet const& ps) {
163  const std::string empty;
164  PropertySet p;
165  _constructor(empty, ps, p);
166 }
167 
168 Event::Event(PropertySet const& ps, PropertySet const& filterable) {
169  const std::string empty;
170  _constructor(empty, ps, filterable);
171 }
172 
173 Event::Event(std::string const& runId, CONST_PTR(PropertySet) psp) {
174  PropertySet p;
175  _constructor(runId, *psp, p);
176 }
177 
178 Event::Event(std::string const& runId, PropertySet const& ps) {
179  PropertySet p;
180  _constructor(runId, ps, p);
181 }
182 
183 Event::Event(std::string const& runId, PropertySet const& ps, PropertySet const& filterable) {
184  _constructor(runId, ps, filterable);
185 }
186 
187 void Event::_constructor(std::string const& runId, PropertySet const& ps, PropertySet const& filterable) {
188  _init();
189 
190  _psp = ps.deepCopy();
191 
192 
193  // do NOT alter the property set we were given. Make a copy of it,
194  // and modify that one.
195 
196  if (!_psp->exists(STATUS)) {
197  _psp->set(STATUS, "unknown");
198  }
199 
200  if (!_psp->exists(EVENTTIME)) {
201  updateEventTime();
202  }
203 
204  // _runId is filled in here and is ignored in the passed PropertySet
205  if (!runId.empty()) {
206  _keywords.insert(RUNID);
207  _psp->set(RUNID, runId);
208  }
209 
210  if (!_psp->exists(TYPE))
211  _psp->set(TYPE, EventTypes::EVENT);
212 
213  // _topic is filled in on publish and is ignored in the passed PropertySet
214  _psp->set(TOPIC, Event::UNINITIALIZED);
215 
216  // _pubTime is filled in on publish and is ignored in the passed PropertySet
217  _psp->set(PUBTIME, (long long)0);
218 
219  if (filterable.nameCount() > 0) {
220  vector<std::string> names = filterable.names();
221 
222  for (std::string name : names) {
223  _keywords.insert(name);
224  }
225 
226  _psp->combine(filterable.PropertySet::deepCopy());
227  }
228 }
229 
230 void Event::populateHeader(cms::TextMessage* msg) const {
231  for (std::string name : _keywords) {
232  std::type_info const& t = _psp->typeOf(name);
233  if (t == typeid(bool)) {
234  msg->setBooleanProperty(name, _psp->get<bool>(name));
235  } else if (t == typeid(short)) {
236  msg->setShortProperty(name, _psp->get<short>(name));
237  } else if (t == typeid(int)) {
238  msg->setIntProperty(name, _psp->get<int>(name));
239  } else if (t == typeid(long)) {
240  msg->setLongProperty(name, _psp->get<long>(name));
241  } else if (t == typeid(long long)) {
242  msg->setLongProperty(name, _psp->get<long long>(name));
243  } else if (t == typeid(double)) {
244  msg->setDoubleProperty(name, _psp->get<double>(name));
245  } else if (t == typeid(float)) {
246  msg->setFloatProperty(name, _psp->get<float>(name));
247  } else if (t == typeid(std::string)) {
248  msg->setStringProperty(name, _psp->get<std::string>(name));
249  } else {
250  std::string msg("Data type represented in "+ name +" is not permitted in event header");
251  throw LSST_EXCEPT(pexExceptions::RuntimeError, msg);
252  }
253  }
254 }
255 
256 
257 long long Event::getEventTime() {
258  return _psp->get<long long>(EVENTTIME);
259 }
260 
261 void Event::setEventTime(long long nsecs) {
262  _psp->set(EVENTTIME, nsecs);
263 }
264 
265 void Event::updateEventTime() {
266  _psp->set(EVENTTIME, (long long)dafBase::DateTime::now().nsecs());
267 }
268 
269 
270 std::string Event::getEventDate() {
271  long long eventTime = _psp->get<long long>(EVENTTIME);
272  dafBase::DateTime dateTime(eventTime);
273 
274  struct tm gmTime = dateTime.gmtime(dafBase::DateTime::UTC);
275  return asctime(&gmTime);
276 }
277 
278 
279 PTR(PropertySet) Event::getCustomPropertySet() const {
280  PTR(PropertySet) psp = _psp->deepCopy();
281 
282  for (std::string keyword : _keywords) {
283  psp->remove(keyword);
284  }
285  return psp;
286 }
287 
288 PTR(PropertySet) Event::getPropertySet() const {
289  if (_psp != 0) {
290  PTR(PropertySet) psp = _psp->deepCopy();
291  return psp;
292  }
293  PTR(PropertySet) psp(new PropertySet);
294  return psp;
295 }
296 
297 void Event::setPubTime(long long t) {
298  _psp->set(PUBTIME, t);
299 }
300 
301 long long Event::getPubTime() {
302  return _psp->get<long long>(PUBTIME);
303 }
304 
305 std::string Event::getPubDate() {
306  long long _pubTime = _psp->get<long long>(PUBTIME);
307  if (_pubTime == 0)
308  return std::string();
309 
310  dafBase::DateTime dateTime(_pubTime);
311 
312  struct tm pubTime = dateTime.gmtime(dafBase::DateTime::UTC);
313  return asctime(&pubTime);
314 }
315 
316 std::string Event::getRunId() {
317  if (_psp->exists(RUNID))
318  return _psp->get<std::string>(RUNID);
319  throw LSST_EXCEPT(pexExceptions::RuntimeError, std::string("property RUNID not found"));
320 }
321 
322 void Event::setRunId(std::string runid) {
323  _keywords.insert(RUNID);
324  _psp->set(RUNID, runid);
325 }
326 
327 std::string Event::getType() {
328  return _psp->get<std::string>(TYPE);
329 }
330 
331 std::string Event::getStatus() {
332  return _psp->get<std::string>(STATUS);
333 }
334 
335 void Event::setStatus(std::string status) {
336  _psp->set(STATUS, status);
337 }
338 
339 void Event::setTopic(std::string topic) {
340  _psp->set(TOPIC, topic);
341 }
342 
343 std::string Event::getTopic() {
344  return _psp->get<std::string>(TOPIC);
345 }
346 
347 void Event::marshall(cms::TextMessage *msg) {
348  PTR(PropertySet) psp;
349 
350  populateHeader(msg);
351  psp = getCustomPropertySet();
352  std::string payload = marshall(*psp);
353  msg->setText(payload);
354 }
355 
356 template<typename T>void Event::add(std::string const& name, std::string const& tag, PropertySet const& ps, boost::property_tree::ptree& child) {
357 
358  std::vector<T> vec = ps.getArray<T>(name);
359 
360  boost::property_tree::ptree children;
361  for (auto iter: vec) {
362  boost::property_tree::ptree pt;
363  pt.put("", iter);
364  children.push_back(std::make_pair(tag, pt));
365  }
366  child.put_child(name, children);
367 }
368 
369 std::string Event::marshall(PropertySet const& ps) {
370  std::vector<std::string> names = ps.paramNames(false);
371 
372  boost::property_tree::ptree child;
373 
374  for (std::string name : names) {
375  if (ps.typeOf(name) == typeid(bool)) {
376  add<bool>(name, "bool", ps, child);
377  } else if (ps.typeOf(name) == typeid(long)) {
378  add<long>(name, "long", ps, child);
379  } else if (ps.typeOf(name) == typeid(long long)) {
380  add<long long>(name, "long long", ps, child);
381  } else if (ps.typeOf(name) == typeid(int)) {
382  add<int>(name, "int", ps, child);
383  } else if (ps.typeOf(name) == typeid(float)) {
384  add<float>(name, "float", ps, child);
385  } else if (ps.typeOf(name) == typeid(double)) {
386  add<double>(name, "double", ps, child);
387  } else if (ps.typeOf(name) == typeid(std::string)) {
388  add<std::string>(name, "string", ps, child);
389  } else if (ps.typeOf(name) == typeid(lsst::daf::base::DateTime)) {
390  std::vector<lsst::daf::base::DateTime> vec = ps.getArray<lsst::daf::base::DateTime>(name);
391  for (lsst::daf::base::DateTime dateTime : vec) {
392  boost::property_tree::ptree pt;
393  pt.put("datetime", (dateTime).nsecs());
394  child.put_child(name, pt);
395  }
396  } else {
397  std::string msg("Couldn't marshall "+name);
398  throw LSST_EXCEPT(pexExceptions::RuntimeError, msg);
399  }
400  }
401  std::ostringstream payload;
402  write_json(payload, child, false);
403 
404  return payload.str();
405 }
406 
409 PTR(PropertySet) Event::processTextMessage(cms::TextMessage* textMessage) {
410  if (textMessage == NULL)
411  return PTR(PropertySet)();
412 
413  std::string text = textMessage->getText();
414 
415  PTR(PropertySet) unmarsh = unmarshall(text);
416  return unmarsh;
417 }
418 
426 bool Event::addDataItem(std::string const& typeInfo, boost::property_tree::ptree& item, std::string const& key, PropertySet& ps) {
427  if (typeInfo == "string") {
428  std::string value = item.get_value<std::string>();
429  ps.add(key, value);
430  } else if (typeInfo == "bool") {
431  bool value = item.get_value<bool>();
432  ps.add(key, value);
433  } else if (typeInfo == "long") {
434  long value = item.get_value<long>();
435  ps.add(key, value);
436  } else if (typeInfo == "long long") {
437  long long value = item.get_value<long long>();
438  ps.add(key, value);
439  } else if (typeInfo == "int") {
440  int value = item.get_value<int>();
441  ps.add(key, value);
442  } else if (typeInfo == "float") {
443  float value = item.get_value<float>();
444  ps.add(key, value);
445  } else if (typeInfo == "double") {
446  double value = item.get_value<double>();
447  ps.add(key, value);
448  } else if (typeInfo == "datetime") {
449  long long value = item.get_value<long long>();
451  } else {
452  return false;
453  }
454  return true;
455 }
456 
462 PTR(PropertySet) Event::parsePropertySet(boost::property_tree::ptree child) {
463  PTR(PropertySet) psp(new PropertySet);
464 
465  BOOST_FOREACH(boost::property_tree::ptree::value_type const &v, child.get_child("")) {
466  std::string label = v.first;
467  BOOST_FOREACH(boost::property_tree::ptree::value_type &v2, child.get_child(label)) {
468  const bool b = addDataItem(v2.first, v2.second, label, *psp);
469  if (!b) {
470  PTR(PropertySet) p2 = parsePropertySet(child.get_child(label));
471  psp->add(label, p2);
472  break;
473  }
474  }
475  }
476  return psp;
477 }
478 
483 PTR(PropertySet) Event::unmarshall(std::string const& text) {
484 
485  boost::property_tree::ptree pt;
486  std::istringstream is (text);
487  read_json(is, pt);
488 
489  PTR(PropertySet) psp(new PropertySet);
490 
491  BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt) {
492  std::string key = v.first;
493 
494  boost::property_tree::ptree child = v.second;
495  BOOST_FOREACH(boost::property_tree::ptree::value_type &v2, child) {
496  std::string key2 = v2.first;
497 
498  const bool b = addDataItem(key2, v2.second, key, *psp);
499  if (!b) {
500  std::string value = v2.second.get_value<std::string>();
501  PTR(PropertySet) p = parsePropertySet(child);
502  psp->add(key, p);
503  break;
504  }
505  }
506  }
507 
508  return psp;
509 }
510 
511 Event::~Event() {
512 }
513 
514 template void Event::add<bool>(std::string const& name, std::string const& tag, PropertySet const& ps, boost::property_tree::ptree& child);
515 
516 template void Event::add<int>(std::string const& name, std::string const& tag, PropertySet const& ps, boost::property_tree::ptree& child);
517 
518 template void Event::add<float>(std::string const& name, std::string const& tag, PropertySet const& ps, boost::property_tree::ptree& child);
519 
520 template void Event::add<double>(std::string const& name, std::string const& tag, PropertySet const& ps, boost::property_tree::ptree& child);
521 
522 template void Event::add<long>(std::string const& name, std::string const& tag,PropertySet const& ps, boost::property_tree::ptree& child);
523 
524 template void Event::add<long long>(std::string const& name, std::string const& tag, PropertySet const& ps, boost::property_tree::ptree& child);
525 
526 template void Event::add<std::string>(std::string const& name, std::string const& tag, PropertySet const& ps, boost::property_tree::ptree& child);
527 
528 }}}
int iter
std::vector< std::string > paramNames(bool topLevelOnly=true) const
Definition: PropertySet.cc:142
static DateTime now(void)
Definition: DateTime.cc:601
Class for handling dates/times, including MJD, UTC, and TAI.
Definition: DateTime.h:58
table::Key< std::string > name
Definition: ApCorrMap.cc:71
size_t nameCount(bool topLevelOnly=true) const
Definition: PropertySet.cc:97
defines EventTypes
#define CONST_PTR(...)
Definition: base.h:47
std::vector< std::string > names(bool topLevelOnly=true) const
Definition: PropertySet.cc:117
lsst::daf::base::PropertySet PropertySet
Definition: Wcs.cc:59
struct tm gmtime(Timescale time) const
Definition: DateTime.cc:534
defines the EventLibrary class
defines the Event class
Interface for DateTime class.
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
std::type_info const & typeOf(std::string const &name) const
Definition: PropertySet.cc:227
int status
Representation of an LSST Event.
Definition: Event.h:61
Class for storing generic metadata.
Definition: PropertySet.h:82
virtual Ptr deepCopy(void) const
Definition: PropertySet.cc:70
#define PTR(...)
Definition: base.h:41
afw::table::Key< double > b
Interface for PropertySet class.
Include files required for standard LSST Exception handling.
void add(std::string const &name, T const &value)
Definition: PropertySet.cc:619
std::vector< T > getArray(std::string const &name) const