1 #include "otsdaq-utilities/ECLWriter/ECLSupervisor.h"
2 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
3 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 #include "otsdaq/SOAPUtilities/SOAPCommand.h"
7 #include "otsdaq/SOAPUtilities/SOAPParameters.h"
8 #include "otsdaq/SOAPUtilities/SOAPUtilities.h"
9 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
10 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
15 #include <xdaq/NamespaceURI.h>
19 #include "otsdaq/TableCore/TableGroupKey.h"
24 #define __MF_SUBJECT__ "ECL"
26 #define XML_ADMIN_STATUS "logbook_admin_status"
27 #define XML_STATUS "logbook_status"
28 #define XML_MOST_RECENT_DAY "most_recent_day"
29 #define XML_TIMEZONE_OFFSET "timezone_offset_hours"
30 #define XML_CATEGORY_ROOT "categories"
31 #define XML_CATEGORY "category"
32 #define XML_ACTIVE_CATEGORY "active_category"
33 #define XML_SAFE_URL "ecl_url"
34 #define XML_RESPONSE_CATEGORY "response_category"
35 #define XML_CATEGORY_CREATE "create_time"
36 #define XML_CATEGORY_CREATOR "creator"
38 #define XML_LOGBOOK_ENTRY "logbook_entry"
39 #define XML_LOGBOOK_ENTRY_SUBJECT "logbook_entry_subject"
40 #define XML_LOGBOOK_ENTRY_TEXT "logbook_entry_text"
41 #define XML_LOGBOOK_ENTRY_FILE "logbook_entry_file"
42 #define XML_LOGBOOK_ENTRY_TIME "logbook_entry_time"
43 #define XML_LOGBOOK_ENTRY_CREATOR "logbook_entry_creator"
44 #define XML_LOGBOOK_ENTRY_HIDDEN "logbook_entry_hidden"
45 #define XML_LOGBOOK_ENTRY_HIDER "logbook_entry_hider"
46 #define XML_LOGBOOK_ENTRY_HIDDEN_TIME "logbook_entry_hidden_time"
51 ECLSupervisor::ECLSupervisor(xdaq::ApplicationStub* stub) : CoreSupervisorBase(stub)
53 __SUP_COUT__ <<
"Constructor." << __E__;
58 this, &ECLSupervisor::MakeSystemLogEntry,
"MakeSystemLogEntry", XDAQ_NS_URI);
62 __SUP_COUT__ <<
"Constructed." << __E__;
66 void ECLSupervisor::init(
void)
70 ECLUser_ = __ENV__(
"ECL_USER_NAME");
71 ECLHost_ = __ENV__(
"ECL_URL");
72 ECLPwd_ = __ENV__(
"ECL_PASSWORD");
73 ECLCategory_ = __ENV__(
"ECL_CATEGORY");
74 CategoryName_ = __ENV__(
"OTS_OWNER") + std::string(
" ots");
78 std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
81 std::chrono::zoned_time<std::chrono::system_clock::duration> utcTime{
"UTC", now};
84 std::chrono::zoned_time<std::chrono::system_clock::duration> localTime{
85 std::chrono::current_zone(), now};
88 std::chrono::seconds offset = std::chrono::duration_cast<std::chrono::seconds>(
89 localTime.get_local_time() - utcTime.get_local_time());
92 timezoneHourOffset_ = offset.count() / 3600;
94 __SUP_COUTV__(timezoneHourOffset_);
96 eclConn_ = std::make_unique<ECLConnection>(ECLUser_, ECLPwd_, ECLHost_);
99 catch(
const std::runtime_error& e)
101 __COUT_ERR__ <<
"ECL environment variables not setup: " << e.what() << __E__;
106 ECLSupervisor::~ECLSupervisor(
void) { destroy(); }
109 void ECLSupervisor::destroy(
void)
114 __SUP_COUT__ <<
"Destructed." << __E__;
118 void ECLSupervisor::defaultPage(xgi::Input* , xgi::Output* out)
120 __COUT__ <<
" active category " << ECLCategory_ << std::endl;
121 *out <<
"<!DOCTYPE HTML><html lang='en'><head><title>ots</title>"
122 << ECLSupervisor::getIconHeaderString() <<
125 <<
"<frameset col='100%' row='100%'><frame "
126 "src='/WebPath/html/Logbook.html?urn="
127 << this->getApplicationDescriptor()->getLocalId()
128 <<
"&active_category=" << ECLCategory_ <<
"'></frameset></html>";
132 std::string ECLSupervisor::getIconHeaderString(
void)
136 return "<link rel='apple-touch-icon' sizes='57x57' href='/WebPath/images/otsdaqIcons/apple-icon-57x57.png'>\
137 <link rel='apple-touch-icon' sizes='60x60' href='/WebPath/images/otsdaqIcons/apple-icon-60x60.png'>\
138 <link rel='apple-touch-icon' sizes='72x72' href='/WebPath/images/otsdaqIcons/apple-icon-72x72.png'>\
139 <link rel='apple-touch-icon' sizes='76x76' href='/WebPath/images/otsdaqIcons/apple-icon-76x76.png'>\
140 <link rel='apple-touch-icon' sizes='114x114' href='/WebPath/images/otsdaqIcons/apple-icon-114x114.png'>\
141 <link rel='apple-touch-icon' sizes='120x120' href='/WebPath/images/otsdaqIcons/apple-icon-120x120.png'>\
142 <link rel='apple-touch-icon' sizes='144x144' href='/WebPath/images/otsdaqIcons/apple-icon-144x144.png'>\
143 <link rel='apple-touch-icon' sizes='152x152' href='/WebPath/images/otsdaqIcons/apple-icon-152x152.png'>\
144 <link rel='apple-touch-icon' sizes='180x180' href='/WebPath/images/otsdaqIcons/apple-icon-180x180.png'>\
145 <link rel='icon' type='image/png' sizes='192x192' href='/WebPath/images/otsdaqIcons/android-icon-192x192.png'>\
146 <link rel='icon' type='image/png' sizes='144x144' href='/WebPath/images/otsdaqIcons/android-icon-144x144.png'>\
147 <link rel='icon' type='image/png' sizes='48x48' href='/WebPath/images/otsdaqIcons/android-icon-48x48.png'>\
148 <link rel='icon' type='image/png' sizes='72x72' href='/WebPath/images/otsdaqIcons/android-icon-72x72.png'>\
149 <link rel='icon' type='image/png' sizes='32x32' href='/WebPath/images/otsdaqIcons/favicon-32x32.png'>\
150 <link rel='icon' type='image/png' sizes='96x96' href='/WebPath/images/otsdaqIcons/favicon-96x96.png'>\
151 <link rel='icon' type='image/png' sizes='16x16' href='/WebPath/images/otsdaqIcons/favicon-16x16.png'>\
152 <link rel='manifest' href='/WebPath/images/otsdaqIcons/manifest.json'>\
153 <meta name='msapplication-TileColor' content='#ffffff'>\
154 <meta name='msapplication-TileImage' content='/WebPath/images/otsdaqIcons/ms-icon-144x144.png'>\
155 <meta name='theme-color' content='#ffffff'>";
165 CorePropertySupervisorBase::setSupervisorProperty(
166 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
168 "*=1 | CreateCategory=-1 | RemoveCategory=-1 | GetCategoryListAdmin=-1 "
169 "| SetActiveCategory=-1" +
170 " | AdminRemoveRestoreEntry=-1");
172 CorePropertySupervisorBase::setSupervisorProperty(
173 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AllowNoLoginRequestTypes,
174 "RefreshLogbook | GetCategoryList");
183 CorePropertySupervisorBase::addSupervisorProperty(
184 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
186 CorePropertySupervisorBase::setSupervisorProperty(
187 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NonXMLRequestTypes,
188 "LogImage | LogReport");
189 CorePropertySupervisorBase::addSupervisorProperty(
190 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
191 "CreateCategory | RemoveCategory | PreviewEntry | AdminRemoveRestoreEntry");
200 HttpXmlDocument& xmlOut,
201 const WebUsers::RequestUserInfo& userInfo)
203 __COUTTV__(requestType);
218 if(0 && requestType ==
"CreateCategory")
225 std::string creator = userInfo.username_;
230 __COUT__ <<
"Created" << std::endl;
232 else if(0 && requestType ==
"RemoveCategory")
239 std::string remover = userInfo.username_;
243 else if(requestType ==
"GetCategoryList")
246 xmlOut.addTextElementToData(
"is_admin",
"0");
247 getCategories(&xmlOut);
249 else if(requestType ==
"SetActiveCategory")
260 webUserSetActiveCategory(CgiDataUtilities::postData(cgiIn,
"Category"), &xmlOut);
262 else if(requestType ==
"RefreshLogbook")
267 std::string Date = CgiDataUtilities::postData(cgiIn,
"Date");
268 uint32_t Duration = CgiDataUtilities::postDataAsInt(cgiIn,
"Duration");
269 std::string CategoryFilter = CgiDataUtilities::postData(cgiIn,
"CategoryFilter");
271 __COUTV__(CategoryFilter);
274 sscanf(Date.c_str(),
"%li", &date);
276 __COUT__ <<
"date " << date <<
" duration " << Duration << std::endl;
277 std::stringstream str;
281 (std::ostringstream*)&str,
282 StringMacros::decodeURIComponent(CategoryFilter));
283 __COUT__ << str.str() << std::endl;
335 __COUT__ <<
"requestType request not recognized." << std::endl;
342 void ECLSupervisor::getCategories(HttpXmlDocument* xmlOut, std::ostringstream* out)
347 __SS__ <<
"No ECL user/host specified for logbook access." << __E__;
351 std::string response, url =
"/A/xml_category_list";
352 eclConn_->Get(url, response);
353 __COUTTV__(response);
355 std::vector<std::string> exps;
395 while((name = StringMacros::extractXmlField(
396 response,
"category", 0, after, &after,
"path=",
"\"")) !=
"")
399 std::string(
"category").size();
401 exps.push_back(name);
420 xmlOut->addTextElementToData(XML_ACTIVE_CATEGORY, ECLCategory_);
421 xmlOut->addTextElementToData(XML_SAFE_URL, eclConn_->getSafeURL());
424 for(
unsigned int i = 0; i < exps.size(); ++i)
427 xmlOut->addTextElementToData(XML_CATEGORY, exps[i]);
429 *out << exps[i] << std::endl;
437 void ECLSupervisor::webUserSetActiveCategory(std::string category,
438 HttpXmlDocument* xmlOut)
441 ECLCategory_ = category;
443 xmlOut->addTextElementToData(
444 XML_ADMIN_STATUS,
"Active category set to " + category +
" successfully.");
453 void ECLSupervisor::refreshLogbook(time_t date,
455 HttpXmlDocument* xmlOut,
456 std::ostringstream* out,
457 std::string categoryFilter)
462 __SS__ <<
"No ECL user/host specified for logbook access." << __E__;
466 if(categoryFilter ==
"")
467 categoryFilter = ECLCategory_;
469 xmlOut->addTextElementToData(XML_ACTIVE_CATEGORY, ECLCategory_);
471 xmlOut->addTextElementToData(XML_RESPONSE_CATEGORY,
474 int64_t mostRecentTime = 0;
481 baseTime = date - timezoneHourOffset_ * 60 * 60 +
486 std::string response, url =
"/E/xml_get?e=" + std::string(
"1843");
488 eclConn_->Get(url, response);
493 std::string response, url =
"/E/xml_search?l=5";
496 eclConn_->Get(url, response);
501 std::string response, url =
"/E/xml_search?l=5";
503 "&c=" + StringMacros::encodeURIComponent(
"Facilities / Building");
505 eclConn_->Get(url, response);
510 std::string response, url =
"/E/xml_search?l=5";
512 StringMacros::encodeURIComponent(
"Facilities . Building");
514 eclConn_->Get(url, response);
520 __COUTTV__(categoryFilter);
521 std::string response, url =
"/E/xml_search?";
525 bool applyCategoryFilter =
false;
526 bool applyInvertedCategoryFilter =
false;
527 std::vector<std::string> acceptCategories;
529 if(categoryFilter.size() && categoryFilter[0] !=
'*' &&
530 categoryFilter[0] !=
'!' && categoryFilter.find(
',') == std::string::npos &&
531 categoryFilter.find(
" / ") == std::string::npos)
533 "l=100&c=" + StringMacros::encodeURIComponent(categoryFilter);
541 applyCategoryFilter =
542 (categoryFilter.size() && categoryFilter[0] !=
'*') ?
true :
false;
543 applyInvertedCategoryFilter =
544 (categoryFilter.size() && categoryFilter[0] ==
'!') ?
true :
false;
545 if(applyCategoryFilter)
547 if(applyInvertedCategoryFilter)
549 StringMacros::getVectorFromString(categoryFilter.substr(1));
551 acceptCategories = StringMacros::getVectorFromString(categoryFilter);
552 __COUTTV__(StringMacros::vectorToString(acceptCategories));
554 __COUTTV__(applyInvertedCategoryFilter);
555 __COUTTV__(applyCategoryFilter);
560 __COUTTV__(baseTime);
561 __COUTTV__(duration);
565 for(
size_t i = 0; i < 24; ++i)
567 __COUTT__ <<
"i-: " << i <<
" "
568 << ((baseTime - i * 60 * 60) / (60 * 60 * 24));
570 time_t modTime = baseTime - i * 60 * 60;
571 std::tm* baseTimeTm =
572 std::localtime(&modTime);
573 char translatedDate[256];
575 translatedDate,
sizeof(translatedDate),
"%Y-%m-%d", baseTimeTm);
576 __COUTTV__(translatedDate);
579 for(
size_t i = 0; i < 24; ++i)
581 __COUTT__ <<
"i+: " << i <<
" "
582 << ((baseTime + i * 60 * 60) / (60 * 60 * 24));
583 time_t modTime = baseTime + i * 60 * 60;
584 std::tm* baseTimeTm =
585 std::localtime(&modTime);
586 char translatedDate[256];
588 translatedDate,
sizeof(translatedDate),
"%Y-%m-%d", baseTimeTm);
589 __COUTTV__(translatedDate);
594 baseTime += 1 * (60 * 60 * 24);
595 std::tm* baseTimeTm = std::localtime(&baseTime);
596 char baseTimeTmBuffer[256];
597 strftime(baseTimeTmBuffer,
sizeof(baseTimeTmBuffer),
"%Y-%m-%d", baseTimeTm);
598 __COUTTV__(baseTimeTmBuffer);
599 url +=
"&b=" + std::string(baseTimeTmBuffer) +
"+00:00:00";
603 duration * (60 * 60 * 24);
604 baseTimeTm = std::localtime(&baseTime);
605 strftime(baseTimeTmBuffer,
sizeof(baseTimeTmBuffer),
"%Y-%m-%d", baseTimeTm);
606 __COUTTV__(baseTimeTmBuffer);
607 url +=
"&a=" + std::string(baseTimeTmBuffer) +
"+00:00:00";
610 eclConn_->Get(url, response);
611 __COUTVS__(3, response);
646 std::string id, author, subject, category, timestamp, files, images, text;
647 size_t after = 0, before = -1, entryCount = 0, lastBefore = -1;
649 std::string preText, postText;
652 StringMacros::rextractXmlField(response,
665 author = StringMacros::extractXmlField(
666 response,
"entry", 0, after,
nullptr,
"author=",
"\"");
667 subject = StringMacros::extractXmlField(
668 response,
"entry", 0, after,
nullptr,
"subject=",
"\"");
669 category = StringMacros::extractXmlField(
670 response,
"entry", 0, after,
nullptr,
"category=",
"\"");
672 if(applyCategoryFilter)
674 bool found = applyInvertedCategoryFilter;
675 for(
const auto& acceptCategory : acceptCategories)
676 if(category == acceptCategory ||
677 category.find(acceptCategory +
"/") != std::string::npos)
679 found = !applyInvertedCategoryFilter;
685 __COUT_TYPE__(TLVL_DEBUG + 10)
686 << __COUT_HDR__ <<
"Skipping unaccepted category: " << category
694 timestamp = StringMacros::extractXmlField(
695 response,
"entry", 0, after,
nullptr,
"timestamp=",
"\"");
696 images = StringMacros::extractXmlField(
697 response,
"entry", 0, after,
nullptr,
"images=",
"\"");
698 files = StringMacros::extractXmlField(
699 response,
"entry", 0, after,
nullptr,
"files=",
"\"");
701 __COUTVS__(2, author);
702 __COUTVS__(2, timestamp);
704 std::istringstream ss(timestamp);
707 &tm,
"%m/%d/%Y %H:%M:%S");
708 time_t t = std::mktime(&tm);
711 __COUTVS__(2, mostRecentTime);
712 if(!date && t > mostRecentTime)
714 __COUTVS__(2, mostRecentTime);
717 text = StringMacros::extractXmlField(response,
718 "pre class=\"html_safe_entry\"",
724 __COUTVS__(2, text.size());
725 if(text.size() == 0 ||
726 foundTextPos > lastBefore)
728 text = StringMacros::extractXmlField(
729 response,
"text", 0, after,
nullptr,
"",
">");
730 __COUTVS__(2, text.size());
733 if(text.size() > std::string(
"Message: 
").size() && text[0] ==
'M' &&
734 text[6] ==
'e' && text[7] ==
':' && text[9] ==
'&' && text[10] ==
'#')
736 std::string(
"Message: 
").size());
740 bool needAttachments =
false;
741 if(atoi(images.c_str()))
743 needAttachments =
true;
744 preText +=
"Attached Images: " + images +
"<br>";
746 if(atoi(files.c_str()))
748 needAttachments =
true;
749 preText +=
"Attached Files: " + files +
"<br>";
754 std::string response, url =
"/E/xml_get?e=" + id;
756 eclConn_->Get(url, response);
757 __COUTVS__(3, response);
759 size_t fileCount = atoi(files.c_str());
760 __COUTV__(fileCount);
761 size_t attachmentAfter = 0;
764 postText +=
"<br><br>=====> Attached Files:";
765 for(
size_t j = 0; j < fileCount; ++j)
767 __COUTTV__(attachmentAfter);
768 std::string furl = StringMacros::extractXmlField(response,
777 std::string fname = StringMacros::extractXmlField(response,
785 __COUTVS__(2, fname);
788 postText +=
"Attached File #" + std::to_string(j + 1) +
": ";
790 "<a target='_blank' href='" + furl +
"'>" + fname +
"</a>";
791 attachmentAfter += 20;
794 size_t imageCount = atoi(images.c_str());
795 __COUTVS__(3, imageCount);
798 postText +=
"<br><br>=====> Attached Images:";
799 for(
size_t j = 0; j < imageCount; ++j)
801 __COUTTV__(attachmentAfter);
802 attachmentAfter = response.find(
"type=\"image\"", attachmentAfter);
803 if(attachmentAfter == std::string::npos)
805 attachmentAfter = response.rfind(
"<attachment", attachmentAfter);
806 if(attachmentAfter == std::string::npos)
809 std::string furl = StringMacros::extractXmlField(response,
818 std::string fname = StringMacros::extractXmlField(response,
826 __COUTVS__(2, fname);
829 postText +=
"Attached Image #" + std::to_string(j + 1) +
": ";
831 "<a target='_blank' href='" + furl +
"'>" + fname +
"</a>";
833 attachmentAfter += 50;
838 auto wrapLinks = [](
const std::string& inputText) -> std::string {
840 std::string::size_type pos = 0;
841 std::string::size_type start;
843 while((start = inputText.find(
"http://", pos)) != std::string::npos ||
844 (start = inputText.find(
"https://", pos)) != std::string::npos)
847 result.append(inputText, pos, start - pos);
850 std::string::size_type end =
851 inputText.find_first_of(
" \t\n!<>(),\"\'", start);
852 if(end == std::string::npos)
854 end = inputText.size();
858 std::string url = inputText.substr(start, end - start);
861 result +=
"<a href=\"" + url +
"\" target=\"_blank\">" + url +
"</a>";
868 result.append(inputText, pos, inputText.size() - pos);
874 preText + (preText.size() ?
"\n<br>" :
"") + wrapLinks(text) + postText;
879 auto entryParent = xmlOut->addTextElementToData(XML_LOGBOOK_ENTRY);
881 xmlOut->addTextElementToParent(
882 XML_LOGBOOK_ENTRY_TIME, std::to_string(t), entryParent);
883 xmlOut->addTextElementToParent(
884 XML_LOGBOOK_ENTRY_CREATOR, author, entryParent);
885 xmlOut->addTextElementToParent(XML_LOGBOOK_ENTRY_TEXT, text, entryParent);
886 xmlOut->addTextElementToParent(
887 XML_LOGBOOK_ENTRY_SUBJECT,
888 category +
" - entry #" +
id +
" - " + subject,
898 __COUTV__(entryCount);
902 xmlOut->addTextElementToData(XML_STATUS,
"1");
904 *out << __COUT_HDR_FL__ <<
"Today: " << time(0) / (60 * 60 * 24) << std::endl;
908 __COUTTV__(mostRecentTime);
910 __COUTTV__(time(0) - mostRecentTime);
911 __COUTTV__((time(0) - mostRecentTime) / (60 * 60 * 24));
912 __COUTTV__(timezoneHourOffset_);
913 for(
size_t i = 0; i < 24; ++i)
914 __COUTT__ <<
"i: " << i <<
" "
915 << ((time(0) - i * 60 * 60 + timezoneHourOffset_ * 60 * 60) /
921 xmlOut->addNumberElementToData(XML_TIMEZONE_OFFSET, timezoneHourOffset_);
926 int64_t mostRecentDayIndex =
927 (mostRecentTime + timezoneHourOffset_ * 60 * 60) / (60 * 60 * 24);
928 int64_t nowDayIndex =
929 (time(0) + timezoneHourOffset_ * 60 * 60) / (60 * 60 * 24);
932 __COUTTV__(mostRecentDayIndex);
933 __COUTTV__(nowDayIndex);
934 __COUTTV__(mostRecentTime);
935 __COUTTV__(((time(0) - mostRecentTime + timezoneHourOffset_ * 60 * 60) /
938 __COUTTV__(nowDayIndex - mostRecentDayIndex);
939 xmlOut->addNumberElementToData(
945 xmlOut->addNumberElementToData(XML_MOST_RECENT_DAY, 0);
956 SOAPParameters parameters(
"EntryText");
957 parameters.addParameter(
"SubjectText");
958 SOAPUtilities::receive(msg, parameters);
959 std::string EntryText =
960 StringMacros::decodeURIComponent(parameters.getValue(
"EntryText"));
961 std::string SubjectText =
962 StringMacros::decodeURIComponent(parameters.getValue(
"SubjectText"));
964 __COUT__ <<
"Received External Supervisor System Entry " << EntryText << std::endl;
965 __COUTV__(SubjectText);
967 std::string retStr =
"Success";
972 __COUT_INFO__ <<
"No ECL user/host specified for log entry: " << EntryText
976 SOAPParameters retParameters(
"Status", retStr);
978 return SOAPUtilities::makeSOAPMessageReference(
"SystemLogEntryStatusResponse",
983 eclEntry.author(StringMacros::escapeString(ECLUser_));
984 eclEntry.category(StringMacros::escapeString(ECLCategory_));
985 eclEntry.subject(StringMacros::escapeString(SubjectText));
989 Form_t::field_sequence fields;
990 std::string users = theRemoteWebUsers_.getActiveUserList();
992 form.name(
"default");
996 std::stringstream ss;
997 ss <<
"Message: " << __E__ << EntryText << __E__ << __E__;
998 ss <<
"This was a System Generated Log Entry from '" << CategoryName_
999 <<
"' at host '" << __ENV__(
"THIS_HOST") <<
"'" << __E__;
1000 ss <<
"Active ots users: " << users << __E__;
1001 ss <<
"USER_DATA: " << __ENV__(
"USER_DATA") << __E__;
1003 << StringMacros::getTimeDurationString(
1004 CorePropertySupervisorBase::getSupervisorUptime())
1006 field =
Field_t(StringMacros::escapeString(ss.str(),
true ),
1008 fields.push_back(field);
1012 eclEntry.form(form);
1016 if(!eclConn_->Post(eclEntry))
1018 __COUT_ERR__ <<
"Failure to post ECL entry." << __E__;
1022 catch(
const std::runtime_error& e)
1024 __SS__ <<
"Exception caught during Logbook ECL connection: " << e.what();
1025 __COUT_ERR__ << ss.str();
1030 SOAPParameters retParameters(
"Status", retStr);
1032 return SOAPUtilities::makeSOAPMessageReference(
"SystemLogEntryStatusResponse",
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
xoap::MessageReference MakeSystemLogEntry(xoap::MessageReference msg)
virtual void setSupervisorPropertyDefaults(void) override
override to control supervisor specific defaults
virtual void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override