diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc index 5adcc6d57a48366815f537c5eba8959fdeb9fd24..a982deac6814733214f25f0f807d4a1d1b76c348 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc @@ -109,6 +109,30 @@ MACScheduler::MACScheduler() : } } + + +// JS: 20200329: This is a working piece of code to test TMSSBridge functionality. +// The actual code is used below in _updatePlannedList, but that requires GCF calls which I don't have (yet) in my dockerimage. + ParameterSet* pParamSet = globalParameterSet(); + std::string tmss_username = pParamSet->getString("TMSSusername", "test"); + std::string tmss_password = pParamSet->getString("TMSSpassword", "test"); + std::string tmss_hostname = pParamSet->getString("TMSShostname", "127.0.0.1"); + int tmss_port = pParamSet->getInt("TMSSport", 8008); + + LOG_INFO_STR ("Trying to connect to the TMSS " << tmss_hostname << ":" << tmss_port << " user/pass:" << tmss_username << "/******" ); + itsTMSSconnection = new TMSSBridge(tmss_hostname, tmss_port, tmss_username, tmss_password); + LOG_INFO ("Connected to the TMSSBridge"); + + Json::Value upcomingSubTasks = itsTMSSconnection->getSubTasksStartingInThreeMinutes(); + + if (!upcomingSubTasks.empty()) { + std::cout << formatString("TMSSCheck:First planned observation (%d) is at %s", upcomingSubTasks[0]["url"].asCString(), upcomingSubTasks[0]["start_time"].asCString()); + } + + std::cout << itsTMSSconnection->getParsetAsText(2000000); + exit(0); + + ASSERTSTR(itsMaxPlanned + itsMaxFinished < MAX_CONCURRENT_OBSERVATIONS, "maxPlannedList + maxFinishedList should be less than " << MAX_CONCURRENT_OBSERVATIONS); @@ -705,9 +729,6 @@ void MACScheduler::_updatePlannedList() // get new list (list is ordered on starttime) of planned observations vector<OTDBtree> plannedDBlist = itsOTDBconnection->getTreeGroup(1, itsPlannedPeriod, itsExclPLcluster); - // to be replaced by TMSS call (do we need a switch?)... - vector<int> subTaskID = itsTMSSconnection->getSubTaskIDStartingInThreeMinutes(currentTime, itsExclPLcluster); - // the subtasksIDs should map somehow on the OTDBtree vector if (!plannedDBlist.empty()) { LOG_DEBUG(formatString("OTDBCheck:First planned observation (%d) is at %s (active over %d seconds)", @@ -716,6 +737,13 @@ void MACScheduler::_updatePlannedList() } // NOTE: do not exit routine on emptylist: we need to write an empty list to clear the DB + Json::Value upcomingSubTasks = itsTMSSconnection->getSubTasksStartingInThreeMinutes(); + + if (!upcomingSubTasks.empty()) { + LOG_DEBUG(formatString("TMSSCheck:First planned observation (%d) is at %s", + upcomingSubTasks[0]["url"].asCString(), upcomingSubTasks[0]["start_time"].asCString())); + } + // make a copy of the current prepared observations (= observations shown in the navigator in the 'future' // list). By eliminating the observations that are in the current SAS list we end up (at the end of this function) // with a list of observations that were in the SASlist the last time but now not anymore. Normally those observations diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in index 02f3dd3620c8961b6ba6d6e894f075f8c67b73d2..6c7077952ad9f4ca3ef618226f2dcbd03d6d66f7 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in @@ -8,8 +8,8 @@ OTDBpassword = boskabouter OTDBpollInterval = 5s # TMSS connection info -TMSShostname = tmss-ua.control.lofar -TMSSport = 8008 +TMSShostname = 127.0.0.1 # tmss-ua.control.lofar +TMSSport = 8000 #8008 TMSSusername = test # TODO: replace test user/pass with secret user/pass which is not stored in git TMSSpassword = test # TODO: replace test user/pass with secret user/pass which is not stored in git diff --git a/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc b/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc index a9d4dfa46202229414657a36d0b225c33e6a29c0..1360e3d50fff61c38470b5cc202f78fcdc85708b 100644 --- a/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc +++ b/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc @@ -21,7 +21,6 @@ // $Id$ #include "TMSSBridge.h" - #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/algorithm/string.hpp> #include <cstdlib> @@ -60,43 +59,23 @@ TMSSBridge::~TMSSBridge() // get all subTaskIDS that should run within three minutes (ordered in time if multiple are found) // for given cluster // -vector<int> TMSSBridge::getSubTaskIDStartingInThreeMinutes(ptime currentTime, string clusterName) +Json::Value TMSSBridge::getSubTasksStartingInThreeMinutes() { - string currentTimeStr = to_iso_extended_string(currentTime); - string queryStr = "/api/?start_time__lt=" + currentTimeStr + "&cluster__name==" + clusterName; - Json::Value result = httpGET(queryStr); - vector<string> urlList = translateHttpResultToSortedUrlList(result); -} - + time_t now = time(0); + ptime lower_limit = from_time_t(now); + ptime upper_limit = from_time_t(now+3*60); -// -// Translate the HTTP result to json format and parse the json format -// How to handle json structure in C++? -// Get the number of taskIDs like python -// json_response = response.json() -// json_response.get('count')) -// ... and results[idx].items('url) -// if multiple found sort on startTime ! -vector<string> TMSSBridge::translateHttpResultToSortedUrlList(Json::Value jsonRoot) -{ - vector<string> urlList{}; - - // Read values - const int nbrTasksFound(jsonRoot["count"].asInt()); - const Json::Value results = jsonRoot["results"]; - for(int idx=0; idx<results.size(); ++idx) { - string urlStr = results[idx]["url"].asString(); - string startTimeStr = results[idx]["start_time"].asString(); - // Only interested in the subTaskID - vector<string>tmp; - boost::split(tmp, urlStr, boost::is_any_of("/subtask/")); - urlList.push_back(tmp.at(1).c_str()); - // TODO: I am lazy now....sort on ascending starttime - } + string queryStr = "/api/subtask/?start_time__gt=" + to_iso_extended_string(lower_limit) + "&start_time__lt=" + to_iso_extended_string(upper_limit) + "&ordering=start_time"; + Json::Value result = httpGETAsJson(queryStr); - return urlList; + return result["results"]; } +std::string TMSSBridge::getParsetAsText(int subtask_id) +{ + string queryStr = "/api/subtask/" + to_string(subtask_id) + "/parset"; + return httpGET(queryStr); +} std::size_t callback(const char* in, std::size_t size, @@ -117,10 +96,8 @@ std::size_t callback(const char* in, // httpGET("/api/subtask/?start_time__lt=2020-03-04T12:03:00" // results in a json string output // -Json::Value TMSSBridge::httpGET(const string& target) +string TMSSBridge::httpGET(const string& target) { - Json::Value jsonData(""); - const std::string url(std::string("http://") + itsHost + std::string(":") + std::to_string(itsPort) + target); CURL* curl = curl_easy_init(); @@ -161,34 +138,32 @@ Json::Value TMSSBridge::httpGET(const string& target) if (httpCode == 200) { std::cout << "\nGot successful response from " << url << std::endl; - - // Response looks good - done using Curl now. Try to parse the results - // and print them out. - Json::Reader jsonReader; - std::string httpResponse(*httpData.get()); - - if (jsonReader.parse(httpResponse, jsonData)) - { - // TODO: - // How we deal with logging in Lofar C++ ? - // for now just do a stdout... - std::cout << "Successfully parsed JSON data" << std::endl; - std::cout << "\nJSON data received:" << std::endl; - std::cout << jsonData.toStyledString() << std::endl; - } - else - { - THROW(TMSSBridgeException, "Could not parse HTTP data as JSON. HTTP data was:\n" + httpResponse); - } + return string(*httpData.get()); } - else + + THROW(TMSSBridgeException, "Couldn't GET from " + url + " exiting with http code " + to_string(httpCode)); +} + +Json::Value TMSSBridge::httpGETAsJson(const string& target) +{ + std::string httpResponse = this->httpGET(target); + + Json::Value jsonData(""); + Json::Reader jsonReader; + if (jsonReader.parse(httpResponse, jsonData)) { - THROW(TMSSBridgeException, "Couldn't GET from " + url + " exiting with http code " + to_string(httpCode)); + // TODO: + // How we deal with logging in Lofar C++ ? + // for now just do a stdout... + std::cout << "Successfully parsed JSON data" << std::endl; + std::cout << "\nJSON data received:" << std::endl; + std::cout << jsonData.toStyledString() << std::endl; + return jsonData; } - return jsonData; -} + THROW(TMSSBridgeException, "Could not parse HTTP data as JSON. HTTP data was:\n" + httpResponse); +} };//MainCU diff --git a/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.h b/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.h index 736dd10e4b3be768e034c0e73fc2df63fb87a4f1..cf1206073e4bb57545e14ec0b3b5144ad3d2ec8b 100644 --- a/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.h +++ b/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.h @@ -44,13 +44,15 @@ public: TMSSBridge (const std::string &hostname, int port, const std::string &username, const std::string &password); ~TMSSBridge (); - vector<int> getSubTaskIDStartingInThreeMinutes(ptime currentTime, string clusterName); + Json::Value getSubTasksStartingInThreeMinutes(); + string getParsetAsText(int subtask_id); // Actually the next method are private, make it public to be able to use in UnitTest++ vector<string> translateHttpResultToSortedUrlList(Json::Value result); // http request to TMSS - Json::Value httpGET(const string& target); + string httpGET(const string& target); + Json::Value httpGETAsJson(const string& target); private: // Copying is not allowed