OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sandesh_message_builder.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <sandesh/sandesh_message_builder.h>
6 
7 using namespace pugi;
8 using namespace std;
9 
10 // SandeshMessage
12 }
13 
14 static bool ParseInteger(const pugi::xml_node &node, int *valuep) {
15  char *endp;
16  *valuep = strtoul(node.child_value(), &endp, 10);
17  return endp[0] == '\0';
18 }
19 
20 static bool ParseUnsignedLong(const pugi::xml_node &node, uint64_t *valuep) {
21  char *endp;
22  *valuep = strtoull(node.child_value(), &endp, 10);
23  return endp[0] == '\0';
24 }
25 
26 // SandeshXMLMessage
28 }
29 
30 bool SandeshXMLMessage::ParseHeader(const xml_node& root,
31  SandeshHeader& header) {
32  for (xml_node node = root.first_child(); node;
33  node = node.next_sibling()) {
34  const char *name(node.name());
35  assert(strcmp(node.last_attribute().name(), "identifier") == 0);
36  int identifier(node.last_attribute().as_int());
37  switch (identifier) {
38  case 1:
39  header.set_Namespace(node.child_value());
40  break;
41  case 2:
42  uint64_t Timestamp;
43  if (!ParseUnsignedLong(node, &Timestamp)) return false;
44  header.set_Timestamp(Timestamp);
45  break;
46  case 3:
47  header.set_Module(node.child_value());
48  break;
49  case 4:
50  header.set_Source(node.child_value());
51  break;
52  case 5:
53  header.set_Context(node.child_value());
54  break;
55  case 6:
56  int SequenceNum;
57  if (!ParseInteger(node, &SequenceNum)) return false;
58  header.set_SequenceNum(SequenceNum);
59  break;
60  case 7:
61  int VersionSig;
62  if (!ParseInteger(node, &VersionSig)) return false;
63  header.set_VersionSig(VersionSig);
64  break;
65  case 8:
66  int Type;
67  if (!ParseInteger(node, &Type)) return false;
68  header.set_Type(static_cast<SandeshType::type>(Type));
69  break;
70  case 9:
71  int Hints;
72  if (!ParseInteger(node, &Hints)) return false;
73  header.set_Hints(Hints);
74  break;
75  case 10:
76  int Level;
77  if (!ParseInteger(node, &Level)) return false;
78  header.set_Level(static_cast<SandeshLevel::type>(Level));
79  break;
80  case 11:
81  header.set_Category(node.child_value());
82  break;
83  case 12:
84  header.set_NodeType(node.child_value());
85  break;
86  case 13:
87  header.set_InstanceId(node.child_value());
88  break;
89  case 14:
90  header.set_IPAddress(node.child_value());
91  break;
92  case 15:
93  int Pid;
94  if (!ParseInteger(node, &Pid)) return false;
95  header.set_Pid(Pid);
96  break;
97  default:
98  SANDESH_LOG(ERROR, __func__ << ": Unknown identifier: " << identifier);
99  break;
100  }
101  }
102  return true;
103 }
104 
105 bool SandeshXMLMessage::Parse(const uint8_t *xml_msg, size_t size) {
106  xml_parse_result result = xdoc_.load_buffer(xml_msg, size,
107  parse_default & ~parse_escapes);
108  if (!result) {
109  SANDESH_LOG(ERROR, __func__ << ": Unable to load Sandesh XML. (status=" <<
110  result.status << ", offset=" << result.offset << "): " <<
111  xml_msg);
112  return false;
113  }
114  xml_node header_node = xdoc_.first_child();
115  if (!ParseHeader(header_node, header_)) {
116  SANDESH_LOG(ERROR, __func__ << ": Sandesh header parse FAILED: " <<
117  xml_msg);
118  return false;
119  }
120  message_node_ = header_node.next_sibling();
121  message_type_ = message_node_.name();
122  if (message_type_.empty()) {
123  SANDESH_LOG(ERROR, __func__ << ": Message type NOT PRESENT: " <<
124  xml_msg);
125  return false;
126  }
127  size_ = size;
128  return true;
129 }
130 
131 const std::string SandeshXMLMessage::ExtractMessage() const {
132  ostringstream sstream;
133  message_node_.print(sstream, "", format_raw | format_no_declaration |
134  format_no_escapes);
135  return sstream.str();
136 }
137 
138 // SandeshSyslogMessage
140 }
141 
142 bool SandeshSyslogMessage::Parse(const uint8_t *xml_msg, size_t size) {
143  xml_parse_result result = xdoc_.load_buffer(xml_msg, size,
144  parse_default & ~parse_escapes);
145  if (!result) {
146  SANDESH_LOG(ERROR, __func__ << ": Unable to load Sandesh Syslog. (status=" <<
147  result.status << ", offset=" << result.offset << "): " <<
148  xml_msg);
149  return false;
150  }
151  message_node_ = xdoc_.first_child();
152  message_type_ = message_node_.name();
153  size_ = size;
154  return true;
155 }
156 
157 // SandeshMessageBuilder
160  if (type == SandeshMessageBuilder::XML) {
162  } else if (type == SandeshMessageBuilder::SYSLOG) {
164  }
165  return NULL;
166 }
167 
168 // SandeshXMLMessageBuilder
170  const uint8_t *xml_msg, size_t size) const {
172  if (!msg->Parse(xml_msg, size)) {
173  delete msg;
174  return NULL;
175  }
176  return msg;
177 }
178 
180 
182 }
183 
185  return &instance_;
186 }
187 
188 // SandeshSyslogMessageBuilder
190  const uint8_t *xml_msg, size_t size) const {
192  msg->Parse(xml_msg, size);
193  return msg;
194 }
195 
197 
199 }
200 
202  return &instance_;
203 }
static SandeshSyslogMessageBuilder * GetInstance()
virtual bool Parse(const uint8_t *data, size_t size)
static SandeshXMLMessageBuilder instance_
virtual SandeshMessage * Create(const uint8_t *data, size_t size) const
#define SANDESH_LOG(_Level, _Msg)
Definition: p/sandesh.h:474
uint8_t type
Definition: load_balance.h:109
static bool ParseInteger(const pugi::xml_node &node, int *valuep)
virtual bool Parse(const uint8_t *data, size_t size)
static SandeshSyslogMessageBuilder instance_
static SandeshXMLMessageBuilder * GetInstance()
virtual const std::string ExtractMessage() const
bool ParseHeader(const pugi::xml_node &root, SandeshHeader &header)
static bool ParseUnsignedLong(const pugi::xml_node &node, uint64_t *valuep)
virtual SandeshMessage * Create(const uint8_t *data, size_t size) const
static SandeshMessageBuilder * GetInstance(Type type)