Skip to content

Commit 1b2acbb

Browse files
authored
ATSK-240 change elog to query logs in batches (ros-industrial#63)
* ATSK-240 change elog to querry logs in batches * ATSK-240 add error handling * ATSK-240 fix elog arg default value
1 parent 0ef2fd9 commit 1b2acbb

File tree

5 files changed

+141
-51
lines changed

5 files changed

+141
-51
lines changed

include/abb_librws/common/rw/elog.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace abb ::rws ::rw ::elog
4343
{
4444
int domain; // Domain of message.
4545
int sequenceNumber; // Sequence number of message in domain.
46-
ElogMessageType messageType; // The elog message type.
46+
ElogMessageType messageType; // The elog message type.
4747
int code; // The elog message code.
4848
std::string sourceName; // The elog message source.
4949
std::tm timestamp; // The time stamp when the event log was generated.

include/abb_librws/v1_0/rw/elog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ namespace abb ::rws ::v1_0 ::rw ::elog
4040
*
4141
* @param client RWSClient
4242
* @param domain domain number
43-
* @param seqnum sequence number
43+
* @param seqnum sequence number to start from. If -1, the last @param limit messages are returned. Default -1.
4444
* @param lang The language in which messages will be returned. English default.
4545
* @return ElogMessage structure
4646
*/
47-
ElogMessage getElogMessage(RWSClient &client, int const domain, int const seqnum, std::string const &lang = Language::ENGLISH);
47+
std::vector<ElogMessage> getElogMessages(RWSClient& client, int const domain, int const seqnum = -1, std::string const& lang = Language::ENGLISH);
4848
}

include/abb_librws/v2_0/rw/elog.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ namespace abb ::rws ::v2_0 ::rw ::elog
4040
*
4141
* @param client RWSClient
4242
* @param domain domain number
43-
* @param seqnum sequence number
43+
* @param seqnum sequence number to start from. If -1, the last @param limit messages are returned. Default -1.
4444
* @param lang The language in which messages will be returned. English default.
45+
* @param limit The number of messages to return. Default 50.
4546
* @return ElogMessage structure
4647
*/
47-
ElogMessage getElogMessage(RWSClient &client, int const domain, int const seqnum, std::string const &lang = Language::ENGLISH);
48+
std::vector<ElogMessage> getElogMessages(RWSClient& client, int const domain, int const seqnum = -1, std::string const& lang = Language::ENGLISH, int const limit = 50);
4849
}

src/v1_0/rw/elog.cpp

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,45 +93,89 @@ namespace abb ::rws ::v1_0 ::rw ::elog
9393
return parseDomains(rws_result);
9494
}
9595

96-
ElogMessage parseElogMessageXml(std::string const xml_string)
96+
std::string concatTextFromNodes(std::vector<Poco::XML::Node*> nodes, std::string separator = " ")
97+
{
98+
std::stringstream ss;
99+
bool separator_flag = false;
100+
for (auto node : nodes)
101+
{
102+
if (separator_flag)
103+
ss << separator;
104+
separator_flag = true;
105+
ss << node->innerText();
106+
}
107+
return ss.str();
108+
}
109+
110+
ElogMessage parseElogNode(Poco::XML::Node* node)
97111
{
98-
Poco::AutoPtr<Poco::XML::Document> rws_result = parseXml(xml_string);
99112
ElogMessage message;
100-
message.messageType = makeElogMessageType(std::stoi(xmlFindTextContent(rws_result, XMLAttribute("class", "msgtype"))));
101-
message.code = std::stoi(xmlFindTextContent(rws_result, XMLAttribute("class", "code")));
102-
message.sourceName;
103-
std::istringstream ss(xmlFindTextContent(rws_result, XMLAttribute("class", "tstamp")));
113+
114+
std::string title = xmlNodeGetAttributeValue(node, "title");
115+
int sep_pos = title.find_last_of("/");
116+
117+
message.domain = 0;
118+
message.sequenceNumber = 0;
119+
if (sep_pos != std::string::npos)
120+
{
121+
try {message.domain = std::stoi(title.substr(9, sep_pos - 9));}
122+
catch (std::out_of_range const& e) {}
123+
catch (std::bad_alloc const& e) {}
124+
catch (std::invalid_argument const& e) {}
125+
126+
try {message.sequenceNumber = std::stoi(title.substr(sep_pos + 1));}
127+
catch (std::out_of_range const& e) {}
128+
catch (std::bad_alloc const& e) {}
129+
catch (std::invalid_argument const& e) {}
130+
}
131+
132+
message.messageType = makeElogMessageType(std::stoi(xmlFindTextContent(node, XMLAttribute("class", "msgtype"))));
133+
message.code = std::stoi(xmlFindTextContent(node, XMLAttribute("class", "code")));
134+
message.sourceName = xmlFindTextContent(node, XMLAttribute("class", "src-name"));
135+
std::istringstream ss(xmlFindTextContent(node, XMLAttribute("class", "tstamp")));
104136
ss >> std::get_time(&message.timestamp, "%Y-%m-%d T %H:%M:%S");
105-
message.title = xmlFindTextContent(rws_result, XMLAttribute("class", "title"));
106-
message.desc = xmlFindTextContent(rws_result, XMLAttribute("class", "desc"));
107-
message.conseqs = xmlFindTextContent(rws_result, XMLAttribute("class", "conseqs"));
108-
message.causes = xmlFindTextContent(rws_result, XMLAttribute("class", "causes"));
109-
message.actions = xmlFindTextContent(rws_result, XMLAttribute("class", "actions"));
137+
message.title = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "title")));
138+
message.desc = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "desc")));
139+
message.conseqs = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "conseqs")));
140+
message.causes = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "causes")));
141+
message.actions = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "actions")));
110142

111-
int argc = std::stoi(xmlFindTextContent(rws_result, XMLAttribute("class", "argc")));
143+
int argc = std::stoi(xmlFindTextContent(node, XMLAttribute("class", "argc")));
112144

113145
for (int i = 1; i <= argc; i++)
114146
{
115147
std::stringstream arg_name;
116148
arg_name << "arg" << i;
117-
auto node = xmlFindNodes(rws_result, XMLAttribute("class", arg_name.str()))[0];
118-
119-
std::string value = node->innerText();
120-
std::string valueType = xmlNodeGetAttributeValue(node, "type");
121-
149+
auto arg_nodes = xmlFindNodes(node, XMLAttribute("class", arg_name.str()));
150+
std::string value = "";
151+
std::string valueType = "STRING";
152+
if (!arg_nodes.empty())
153+
{
154+
value = arg_nodes[0]->innerText();
155+
valueType = xmlNodeGetAttributeValue(arg_nodes[0], "type");
156+
}
122157
message.argv[i] = makeElogMessageArg(valueType, value);
123158
}
124159
return message;
125160
}
126161

127-
ElogMessage getElogMessage(RWSClient &client, int const domain, int const seqnum, std::string const &lang)
162+
std::vector<ElogMessage> parseElogMessagesXml(std::string const xml_string)
163+
{
164+
Poco::AutoPtr<Poco::XML::Document> rws_result = parseXml(xml_string);
165+
std::vector<ElogMessage> messages;
166+
auto nodes = xmlFindNodes(rws_result, XMLAttribute("class", "elog-message-li"));
167+
for (auto node : nodes)
168+
messages.push_back(parseElogNode(node));
169+
return messages;
170+
}
171+
172+
std::vector<ElogMessage> getElogMessages(RWSClient& client, int const domain, int const seqnum, std::string const& lang)
128173
{
129174
std::stringstream uri;
130-
uri << "/rw/elog/" << domain << "/" << seqnum << "?lang=" << lang;
175+
uri << "/rw/elog/" << domain << "?lang=" << lang << "&order=lifo";
176+
if (seqnum >= 0) uri << "&elogseqnum=" << seqnum;
131177
POCOResult poco_result = client.httpGet(uri.str());
132-
ElogMessage message = parseElogMessageXml(poco_result.content());
133-
message.domain = domain;
134-
message.sequenceNumber = seqnum;
135-
return message;
178+
std::vector<ElogMessage> messages = parseElogMessagesXml(poco_result.content());
179+
return messages;
136180
}
137181
}

src/v2_0/rw/elog.cpp

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,45 +93,90 @@ namespace abb ::rws ::v2_0 ::rw ::elog
9393
return parseDomains(rws_result);
9494
}
9595

96-
ElogMessage parseElogMessageXml(std::string const xml_string)
96+
std::string concatTextFromNodes(std::vector<Poco::XML::Node*> nodes, std::string separator = " ")
97+
{
98+
std::stringstream ss;
99+
bool separator_flag = false;
100+
for (auto node : nodes)
101+
{
102+
if (separator_flag)
103+
ss << separator;
104+
separator_flag = true;
105+
ss << node->innerText();
106+
}
107+
return ss.str();
108+
}
109+
110+
ElogMessage parseElogNode(Poco::XML::Node* node)
97111
{
98-
Poco::AutoPtr<Poco::XML::Document> rws_result = parseXml(xml_string);
99112
ElogMessage message;
100-
message.messageType = makeElogMessageType(std::stoi(xmlFindTextContent(rws_result, XMLAttribute("class", "msgtype"))));
101-
message.code = std::stoi(xmlFindTextContent(rws_result, XMLAttribute("class", "code")));
102-
message.sourceName;
103-
std::istringstream ss(xmlFindTextContent(rws_result, XMLAttribute("class", "tstamp")));
113+
114+
std::string title = xmlNodeGetAttributeValue(node, "title");
115+
int sep_pos = title.find_last_of("/");
116+
117+
message.domain = 0;
118+
message.sequenceNumber = 0;
119+
if (sep_pos != std::string::npos)
120+
{
121+
try {message.domain = std::stoi(title.substr(9, sep_pos - 9));}
122+
catch (std::out_of_range const& e) {}
123+
catch (std::bad_alloc const& e) {}
124+
catch (std::invalid_argument const& e) {}
125+
126+
try {message.sequenceNumber = std::stoi(title.substr(sep_pos + 1));}
127+
catch (std::out_of_range const& e) {}
128+
catch (std::bad_alloc const& e) {}
129+
catch (std::invalid_argument const& e) {}
130+
}
131+
132+
message.messageType = makeElogMessageType(std::stoi(xmlFindTextContent(node, XMLAttribute("class", "msgtype"))));
133+
message.code = std::stoi(xmlFindTextContent(node, XMLAttribute("class", "code")));
134+
message.sourceName = xmlFindTextContent(node, XMLAttribute("class", "src-name"));
135+
std::istringstream ss(xmlFindTextContent(node, XMLAttribute("class", "tstamp")));
104136
ss >> std::get_time(&message.timestamp, "%Y-%m-%d T %H:%M:%S");
105-
message.title = xmlFindTextContent(rws_result, XMLAttribute("class", "title"));
106-
message.desc = xmlFindTextContent(rws_result, XMLAttribute("class", "desc"));
107-
message.conseqs = xmlFindTextContent(rws_result, XMLAttribute("class", "conseqs"));
108-
message.causes = xmlFindTextContent(rws_result, XMLAttribute("class", "causes"));
109-
message.actions = xmlFindTextContent(rws_result, XMLAttribute("class", "actions"));
137+
message.title = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "title")));
138+
message.desc = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "desc")));
139+
message.conseqs = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "conseqs")));
140+
message.causes = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "causes")));
141+
message.actions = concatTextFromNodes(xmlFindNodes(node, XMLAttribute("class", "actions")));
110142

111-
int argc = std::stoi(xmlFindTextContent(rws_result, XMLAttribute("class", "argc")));
143+
int argc = std::stoi(xmlFindTextContent(node, XMLAttribute("class", "argc")));
112144

113145
for (int i = 1; i <= argc; i++)
114146
{
115147
std::stringstream arg_name;
116148
arg_name << "arg" << i;
117-
auto node = xmlFindNodes(rws_result, XMLAttribute("class", arg_name.str()))[0];
118-
119-
std::string value = node->innerText();
120-
std::string valueType = xmlNodeGetAttributeValue(node, "type");
121-
149+
auto arg_nodes = xmlFindNodes(node, XMLAttribute("class", arg_name.str()));
150+
std::string value = "";
151+
std::string valueType = "STRING";
152+
if (!arg_nodes.empty())
153+
{
154+
value = arg_nodes[0]->innerText();
155+
valueType = xmlNodeGetAttributeValue(arg_nodes[0], "type");
156+
}
122157
message.argv[i] = makeElogMessageArg(valueType, value);
123158
}
124159
return message;
125160
}
126161

127-
ElogMessage getElogMessage(RWSClient &client, int const domain, int const seqnum, std::string const &lang)
162+
std::vector<ElogMessage> parseElogMessagesXml(std::string const xml_string)
163+
{
164+
Poco::AutoPtr<Poco::XML::Document> rws_result = parseXml(xml_string);
165+
std::vector<ElogMessage> messages;
166+
auto nodes = xmlFindNodes(rws_result, XMLAttribute("class", "elog-message-li"));
167+
for (auto node : nodes)
168+
messages.push_back(parseElogNode(node));
169+
return messages;
170+
}
171+
172+
std::vector<ElogMessage> getElogMessages(RWSClient& client, int const domain, int const seqnum, std::string const& lang, int const limit)
128173
{
129174
std::stringstream uri;
130-
uri << "/rw/elog/" << domain << "/" << seqnum << "?lang=" << lang;
175+
uri << "/rw/elog/" << domain << "?lang=" << lang << "&order=lifo";
176+
if (seqnum >= 0) uri << "&elogseqnum=" << seqnum;
177+
if (limit > 0) uri << "&limit=" << limit;
131178
POCOResult poco_result = client.httpGet(uri.str());
132-
ElogMessage message = parseElogMessageXml(poco_result.content());
133-
message.domain = domain;
134-
message.sequenceNumber = seqnum;
135-
return message;
179+
std::vector<ElogMessage> messages = parseElogMessagesXml(poco_result.content());
180+
return messages;
136181
}
137182
}

0 commit comments

Comments
 (0)