Commit 1204163444396ab8bf480030c7a5028b4e7fcdee

Authored by Jürgen Knödlseder
1 parent c93d18a6

Integrate code from GVOTable branch of Thierry Louge.

include/GVOClient.hpp
... ... @@ -32,7 +32,7 @@
32 32 #include "GBase.hpp"
33 33 #include "GXml.hpp"
34 34 #include "GXmlNode.hpp"
35   -
  35 +#include "GFits.hpp"
36 36  
37 37 /***********************************************************************//**
38 38 * @class GVOClient
... ... @@ -74,8 +74,9 @@ public:
74 74 bool ping_hub(void) const;
75 75 void shutdown_hub(void) const;
76 76 GXml execute(const std::string& request) const;
  77 + void publish(const GFitsHDU& hdu);
77 78 std::string print(const GChatter& chatter = NORMAL) const;
78   -
  79 +
79 80 protected:
80 81 // Protected methods
81 82 void init_members(void);
... ... @@ -97,7 +98,7 @@ protected:
97 98 bool response_is_valid(const GXml& xml) const;
98 99 int response_error_code(const GXml& xml) const;
99 100 std::string response_error_message(const GXml& xml) const;
100   -
  101 +
101 102 // Protected data area
102 103 std::string m_name; //!< Client name
103 104 std::string m_secret; //!< Secret Hub key
... ...
include/GVOHub.hpp
... ... @@ -103,19 +103,22 @@ protected:
103 103 std::vector<std::string> get_subscriptions(const GXml& xml) const;
104 104 std::string get_callback_url(const GXml& xml) const;
105 105 std::string get_hub_lockfile(void) const;
106   - void send_notifications(const std::string& method,
  106 + void send_notifications(const std::string& method,
107 107 const std::string& client);
  108 + void send_notifications(const std::string& method,
  109 + const std::string& client,
  110 + const GXml& xml);
  111 + void broadcast(const GXml& xml, const socklen_t& sock);
  112 + std::string get_mtype(const GXml& xml) const;
  113 + std::string get_destination(const GXml& xml) const;
108 114  
109 115 // Low-level methods
110 116 void create_samp_file(void) const;
111   - void delete_samp_file(void) const;
112   - int get_socket(void);
113 117 void post_samp_ok(const socklen_t& sock) const;
114 118 void post_samp_void(const socklen_t& sock) const;
115 119 void post_string(const std::string& content, const socklen_t& sock) const;
116 120 void notify(const std::string& url, const std::string& notification) const;
117 121 std::string random_string(const size_t& length) const;
118   - std::string hub_url(void) const;
119 122  
120 123 // Protected structure
121 124 struct client {
... ... @@ -135,12 +138,13 @@ protected:
135 138  
136 139 // Protected members
137 140 std::string m_secret; //!< Secret Hub key
  141 + std::string m_hub_url; //!< The XML-RPC endpoint for communication with the hub
138 142 std::string m_hub_host; //!< Hub host
139 143 std::string m_hub_port; //!< Hub port
140 144 std::string m_hub_path; //!< Hub path
141 145 std::string m_version; //!< The version of the SAMP Standard Profile implemented by the hub
142 146 std::string m_hub_id; //!< Hub identifier used by the hub when it sends message itself rather than forwarding from others
143   - int m_socket; //!< Hub socket
  147 + socklen_t m_socket; //!< Hub socket
144 148 bool m_shutdown; //!< Shutdown request
145 149 std::vector<client> m_clients; //!< Clients
146 150 };
... ...
src/vo/GVOClient.cpp
... ... @@ -34,6 +34,7 @@
34 34 #include <unistd.h> // close() function
35 35 #include <netdb.h> // getaddrinfo() function
36 36 #include <sys/socket.h> // socket(), connect() functions
  37 +#include <fstream>
37 38 #include "GVOClient.hpp"
38 39 #include "GVOHub.hpp"
39 40 #include "GException.hpp"
... ... @@ -359,6 +360,47 @@ GXml GVOClient::execute(const std::string&amp; request) const
359 360  
360 361  
361 362 /***********************************************************************//**
  363 + * @brief Publish FITS HDU
  364 + *
  365 + * @param[in] hdu FITS HDU
  366 + *
  367 + * Publishes a FITS HDU.
  368 + ***************************************************************************/
  369 +void GVOClient::publish(const GFitsHDU& hdu)
  370 +{
  371 + // Save FITS HDU into a temporary file
  372 + std::string samp_share = std::tmpnam(NULL);
  373 + GFits fits;
  374 + fits.append(hdu);
  375 + fits.saveto(samp_share, true);
  376 +
  377 + // Compose notification to be passed to the Hub
  378 + std::string hub_command = "";
  379 + hub_command.append("<?xml version=\"1.0\"?>\n");
  380 + hub_command.append("<methodCall>");
  381 + hub_command.append(" <methodName>samp.hub.notifyAll</methodName>\n");
  382 + hub_command.append(" <params>\n");
  383 + hub_command.append(" <param><value>image.load.fits</value></param>\n");
  384 + hub_command.append(" <param><value>"+m_secret+"</value></param>\n");
  385 + hub_command.append(" <param><value><struct>\n");
  386 + hub_command.append(" <member><name>samp.params</name><value><struct>\n");
  387 + hub_command.append(" <member><name>name</name><value>Gammalib_FITS_FILE</value></member>\n");
  388 + hub_command.append(" <member><name>url</name><value>file://localhost"+samp_share+"</value></member>\n");
  389 + hub_command.append(" <member><name>image-id</name><value>Gammalib Data</value></member>\n");
  390 + hub_command.append(" </struct></value></member>\n");
  391 + hub_command.append(" <member><name>samp.mtype</name><value>image.load.fits</value></member>\n");
  392 + hub_command.append(" </struct></value></param>\n");
  393 + hub_command.append(" </params>\n</methodCall>\n");
  394 +
  395 + // Send notification
  396 + execute(hub_command);
  397 +
  398 + // Return
  399 + return;
  400 +}
  401 +
  402 +
  403 +/***********************************************************************//**
362 404 * @brief Print VO client information
363 405 *
364 406 * @param[in] chatter Chattiness (defaults to NORMAL).
... ... @@ -517,7 +559,7 @@ bool GVOClient::find_hub(void)
517 559 if (!lockurl.empty()) {
518 560  
519 561 // If we have a file:// prefix then strip it now. This is a kluge
520   - // and should be replaced by a method that allows opening any kind
  562 + // and should be remplaced by a method that allows opening any kind
521 563 // of URL
522 564 if (lockurl.compare(0, 7, "file://") == 0) {
523 565 lockurl = lockurl.substr(7, std::string::npos);
... ... @@ -955,6 +997,7 @@ std::string GVOClient::receive_string(void) const
955 997 int n = 0;
956 998 do {
957 999 n = gammalib::recv(m_socket, buffer, 1000, 0, timeout);
  1000 + //n = recv(m_socket, buffer, 1000, 0);
958 1001 if (n > 0) {
959 1002 buffer[n] = '\0';
960 1003 result.append(std::string(buffer));
... ... @@ -1073,7 +1116,7 @@ std::string GVOClient::get_hub_lockfile(void) const
1073 1116 char* hub_ptr = std::getenv("SAMP_HUB");
1074 1117 if (hub_ptr != NULL) {
1075 1118  
1076   - // Check for mandatory std-lockurl: prefix (no other prefix is
  1119 + // Check for mandatory std-lockurl: prefix (no other prefixe is
1077 1120 // supported so far)
1078 1121 std::string lockurl = std::string(hub_ptr);
1079 1122 if (lockurl.compare(0, 12, "std-lockurl:") == 0) {
... ... @@ -1083,7 +1126,7 @@ std::string GVOClient::get_hub_lockfile(void) const
1083 1126  
1084 1127 } // endif: std-lockurl: prefix found
1085 1128  
1086   - } // endif: SAMP_HUB environment variable found
  1129 + }
1087 1130  
1088 1131 // ... otherwise the lockfile should be $HOME/.samp
1089 1132 else {
... ...
src/vo/GVOHub.cpp
... ... @@ -47,15 +47,14 @@
47 47  
48 48 /* __ Method name definitions ____________________________________________ */
49 49 #define G_START_HUB "GVOHub::start_hub()"
50   -#define G_START_SOCKET "GVOHub::start_socket()"
51 50  
52 51 /* __ Macros _____________________________________________________________ */
53 52  
54 53 /* __ Coding definitions _________________________________________________ */
55 54  
56 55 /* __ Debug definitions __________________________________________________ */
57   -//#define G_CONSOLE_DUMP
58   -//#define G_SHOW_MESSAGE
  56 +#define G_CONSOLE_DUMP
  57 +#define G_SHOW_MESSAGE
59 58  
60 59  
61 60 /*==========================================================================
... ... @@ -86,7 +85,7 @@ GVOHub::GVOHub(const GVOHub&amp; hub)
86 85 {
87 86 // Initialise members
88 87 init_members();
89   -
  88 +
90 89 // Copy members
91 90 copy_members(hub);
92 91  
... ... @@ -180,6 +179,9 @@ GVOHub* GVOHub::clone(void) const
180 179 ***************************************************************************/
181 180 void GVOHub::start(void)
182 181 {
  182 + // Create SAMP file
  183 + create_samp_file();
  184 +
183 185 // Start Hub
184 186 start_hub();
185 187  
... ... @@ -208,7 +210,7 @@ std::string GVOHub::print(const GChatter&amp; chatter) const
208 210 // Append Hub information
209 211 result.append("\n"+gammalib::parformat("Hub identifier")+m_hub_id);
210 212 result.append("\n"+gammalib::parformat("Hub key")+m_secret);
211   - result.append("\n"+gammalib::parformat("Hub URL")+hub_url());
  213 + result.append("\n"+gammalib::parformat("Hub URL")+m_hub_url);
212 214 result.append("\n"+gammalib::parformat("Hub host")+m_hub_host);
213 215 result.append("\n"+gammalib::parformat("Hub port")+m_hub_port);
214 216 result.append("\n"+gammalib::parformat("Hub path")+m_hub_path);
... ... @@ -238,6 +240,7 @@ void GVOHub::init_members(void)
238 240 m_hub_host = "127.0.0.1";
239 241 m_hub_port = "2526";
240 242 m_hub_path = "xmlrpc";
  243 + m_hub_url = "http://"+m_hub_host+":"+m_hub_port+"/"+m_hub_path;
241 244 m_version = "1.3";
242 245 m_hub_id = "gammalib_hub";
243 246 m_socket = -1; // Signals no socket
... ... @@ -258,6 +261,7 @@ void GVOHub::copy_members(const GVOHub&amp; hub)
258 261 {
259 262 // Copy members
260 263 m_secret = hub.m_secret;
  264 + m_hub_url = hub.m_hub_url;
261 265 m_hub_host = hub.m_hub_host;
262 266 m_hub_port = hub.m_hub_port;
263 267 m_hub_path = hub.m_hub_path;
... ... @@ -284,7 +288,8 @@ void GVOHub::free_members(void)
284 288 }
285 289  
286 290 // Remove lockfile
287   - delete_samp_file();
  291 + std::string lockurl = get_hub_lockfile();
  292 + std::remove(lockurl.c_str());
288 293  
289 294 // Return
290 295 return;
... ... @@ -301,13 +306,46 @@ void GVOHub::free_members(void)
301 306 ***************************************************************************/
302 307 void GVOHub::start_hub(void)
303 308 {
304   - // Get socket
305   - m_socket = get_socket();
306   -
307   - // Create SAMP file
308   - create_samp_file();
  309 + // Prepare TCP/IP structure
  310 + struct sockaddr_in serv_addr;
  311 + std::memset(&serv_addr, 0, sizeof(serv_addr));
  312 + serv_addr.sin_family = AF_INET;
  313 + serv_addr.sin_addr.s_addr = inet_addr(m_hub_host.c_str());
  314 + serv_addr.sin_port = htons(gammalib::toint(m_hub_port));
  315 +
  316 + // Create Hub socket
  317 + m_socket = socket(AF_INET, SOCK_STREAM, 0);
  318 +
  319 + // Creation of hub main socket
  320 + if (m_socket < 0) {
  321 + std::string msg = "Unable to create Hub socket. Errno="+
  322 + gammalib::str(errno);
  323 + throw GException::runtime_error(G_START_HUB, msg);
  324 + }
  325 +
  326 + // Set hub main socket to allow multiple connections
  327 + int opt = 1;
  328 + if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0) {
  329 + std::string msg = "Unable to set Hub socket to multiple connections."
  330 + " Errno="+gammalib::str(errno);
  331 + throw GException::runtime_error(G_START_HUB, msg);
  332 + }
  333 + #ifdef SO_REUSEPORT
  334 + if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEPORT, (char*)&opt, sizeof(opt)) < 0) {
  335 + std::string msg = "Unable to set Hub socket to multiple connections."
  336 + " Errno="+gammalib::str(errno);
  337 + throw GException::runtime_error(G_START_HUB, msg);
  338 + }
  339 + #endif
  340 +
  341 + // Server socket is opened. Now, bind it to the port, with family etc.
  342 + if (bind(m_socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
  343 + std::string msg = "Unable to bind Hub socket to server socket. Errno="+
  344 + gammalib::str(errno);
  345 + throw GException::runtime_error(G_START_HUB, msg);
  346 + }
309 347  
310   - // Start listening for the clients: 5 requests simultaneously pending
  348 + // Now start listening for the clients: 5 requests simultaneously pending
311 349 // at maximum
312 350 if (listen(m_socket, 5) < 0) {
313 351 std::string msg = "Unable to start listening on Hub socket. Errno="+
... ... @@ -323,7 +361,7 @@ void GVOHub::start_hub(void)
323 361 while (1) {
324 362  
325 363 // Accept connection from the client
326   - int socket = accept(m_socket, (struct sockaddr *)&cli_addr, &clilen);
  364 + socklen_t socket = accept(m_socket, (struct sockaddr *)&cli_addr, &clilen);
327 365 if (socket < 0) {
328 366 std::string msg = "Client connection to socket not accepted.";
329 367 throw GException::runtime_error(G_START_HUB, msg);
... ... @@ -347,9 +385,6 @@ void GVOHub::start_hub(void)
347 385 close(m_socket);
348 386 m_socket = -1;
349 387  
350   - // Delete SAMP file
351   - delete_samp_file();
352   -
353 388 // Return
354 389 return;
355 390 }
... ... @@ -395,11 +430,12 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
395 430  
396 431 // Extract response into an XML object
397 432 GXml xml;
  433 +
398 434 size_t start = message.find("<?xml");
399 435 if (start != std::string::npos) {
400 436 xml = GXml(message.substr(start, std::string::npos));
401 437 }
402   -
  438 +
403 439 // Get methodName value
404 440 std::string method_called;
405 441 const GXmlNode* node = xml.element("methodCall > methodName");
... ... @@ -446,11 +482,18 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
446 482 else if (method_called.compare("samp.hub.getMetadata") == 0) {
447 483 request_get_metadata(xml, sock);
448 484 }
  485 + else if (method_called.compare("table.load.votable") == 0) {
  486 + request_ping(sock);
  487 + }
449 488 else if (method_called.compare("samp.hub.notify") == 0) {
450 489 request_ping(sock);
451 490 }
452 491 else if (method_called.compare("samp.hub.notifyAll") == 0) {
453   - request_ping(sock);
  492 + #if defined(G_CONSOLE_DUMP)
  493 + std::cout << "==========================================" << std::endl;
  494 + std::cout << "samp.hub.notifyAll" << std::endl;
  495 + #endif
  496 + broadcast(xml, sock);
454 497 }
455 498 else if (method_called.compare("samp.hub.call") == 0) {
456 499 request_ping(sock);
... ... @@ -561,7 +604,7 @@ void GVOHub::request_register(const GXml&amp; xml, const socklen_t&amp; sock)
561 604 response.append(" </member>\n");
562 605 response.append(" <member>\n");
563 606 response.append(" <name>samp.url-translator</name>\n");
564   - response.append(" <value>"+hub_url()+"</value>\n");
  607 + response.append(" <value>"+m_hub_url+"</value>\n");
565 608 response.append(" </member>\n");
566 609 response.append(" </struct></value></param>\n");
567 610 response.append("</params>\n");
... ... @@ -743,7 +786,7 @@ void GVOHub::request_set_xml_rpc_callback(const GXml&amp; xml,
743 786 if (i != -1) {
744 787  
745 788 // Get callback URL
746   - //std::string client_url = get_callback_url(xml);
  789 + std::string client_url = get_callback_url(xml);
747 790  
748 791 // Set callback URL
749 792 m_clients[i].url = get_callback_url(xml);
... ... @@ -869,9 +912,8 @@ void GVOHub::request_get_registered_clients(const GXml&amp; xml, const socklen_t&amp; so
869 912  
870 913 // Declare message
871 914 std::string msg = "";
872   -
873 915 // Set response
874   - msg.append("<?xml version=\'1.0\' encoding=\"UTF-8\"?>\n");
  916 + msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
875 917 msg.append("<methodResponse>\n");
876 918 msg.append("<params>\n");
877 919 msg.append(" <param><value><array><data>\n");
... ... @@ -890,7 +932,6 @@ void GVOHub::request_get_registered_clients(const GXml&amp; xml, const socklen_t&amp; so
890 932 msg.append(" </data></array></value></param>\n");
891 933 msg.append("</params>\n");
892 934 msg.append("</methodResponse>\n");
893   -
894 935 // Post response
895 936 post_string(msg, sock);
896 937  
... ... @@ -915,29 +956,16 @@ void GVOHub::request_get_subscribed_clients(const GXml&amp; xml, const socklen_t&amp; so
915 956 std::cout << "GVOHub::request_get_subscribed_clients" << std::endl;
916 957 #endif
917 958  
918   -/*
919   - std::string buffer;
920   - const int n = 1000;
921   - char line[n];
922   - FILE* fptr = fopen("SAMP-registered.txt", "r");
923   - if (fptr != NULL) {
924   - while (fgets(line, n, fptr) != NULL) {
925   -
926   - // Convert line to C++ string
927   - std::string cline = std::string(line);
  959 + // Declare message
  960 + std::string msg = "";
928 961  
929   - // Check for secret key
930   - if (cline.compare(0, 10, "Registered") == 0) {
931   - buffer = gammalib::strip_chars(cline.substr(10, std::string::npos), "\r\n");
932   - }
933   - }
934   -
935   - // Closes file
936   - fclose(fptr);
937   -*/
  962 + msg.append("<?xml version=\'1.0\' encoding=\"UTF-8\"?>\n");
  963 + msg.append("<methodResponse>\n");
  964 + msg.append("<params>\n");
  965 + msg.append(" <param><value><struct><member><name>c0</name><value><struct></struct></value></member><member><name>gammalib_hub</name><value><struct></struct></value></member></struct></value></param></params></methodResponse>");
938 966  
939   - // Post void message
940   - post_samp_void(sock);
  967 + // Post response
  968 + post_string(msg, sock);
941 969  
942 970 // Return
943 971 return;
... ... @@ -1079,6 +1107,51 @@ void GVOHub::request_get_metadata(const GXml&amp; xml, const socklen_t&amp; sock)
1079 1107 return;
1080 1108 }
1081 1109  
  1110 +/***********************************************************************//**
  1111 + * @brief Broadcasts a message
  1112 + *
  1113 + * @param[in] xml XML message sent by client.
  1114 + * @param[in] sock Socket.
  1115 + *
  1116 + * Broadcasts an image to every registered client.
  1117 + ***************************************************************************/
  1118 +void GVOHub::broadcast(const GXml& xml, const socklen_t& sock)
  1119 +{
  1120 + // Header
  1121 +
  1122 + // Get client index
  1123 + int i = get_client_index(xml);
  1124 +
  1125 + // Get message mtype
  1126 + std::string mtype = get_mtype(xml);
  1127 + #if defined(G_CONSOLE_DUMP)
  1128 + std::cout<<"mtype is: " +mtype + " i value: " + gammalib::str(i)<<std::endl;
  1129 + #endif
  1130 + post_samp_void(sock);
  1131 +
  1132 + if (mtype == "image.load.fits") {
  1133 + #if defined(G_CONSOLE_DUMP)
  1134 + std::cout<<"notifying image.load.fits"<<std::endl;
  1135 + #endif
  1136 +
  1137 + // Send notifications
  1138 + send_notifications("image.load.fits",m_clients[i].reference,xml);
  1139 + }
  1140 +
  1141 + if (mtype == "table.load.votable") {
  1142 +
  1143 + // Send notifications
  1144 + send_notifications("table.load.votable",m_clients[i].reference,xml);
  1145 + }
  1146 +
  1147 + #if defined(G_CONSOLE_DUMP)
  1148 + std::cout<<"Returning from broadcast function"<<std::endl;
  1149 + #endif
  1150 +
  1151 + // Return
  1152 + return;
  1153 +
  1154 +}
1082 1155  
1083 1156 /***********************************************************************//**
1084 1157 * @brief Handles Hub shutdown requests
... ... @@ -1408,11 +1481,14 @@ std::string GVOHub::get_hub_lockfile(void) const
1408 1481 * @param[in] method Name of the method
1409 1482 * @param[in] client Reference of the client
1410 1483 *
1411   - * The method send notifications to all registered clients that request so.
  1484 + * Send notifications to all registered clients that request so.
1412 1485 ***************************************************************************/
1413 1486 void GVOHub::send_notifications(const std::string& method,
1414 1487 const std::string& client)
1415 1488 {
  1489 + #if defined(G_CONSOLE_DUMP)
  1490 + std::cout << "GVOHub::send_notifications 1st form" << std::endl;
  1491 + #endif
1416 1492 // Loop over all clients
1417 1493 for (int i = 0; i < m_clients.size(); ++i) {
1418 1494  
... ... @@ -1459,7 +1535,7 @@ void GVOHub::send_notifications(const std::string&amp; method,
1459 1535 notify(m_clients[i].url, msg);
1460 1536  
1461 1537 }
1462   -
  1538 +
1463 1539 // Unregister
1464 1540 else if (method == "samp.hub.event.unregister") {
1465 1541  
... ... @@ -1579,7 +1655,7 @@ void GVOHub::send_notifications(const std::string&amp; method,
1579 1655 // Post notification
1580 1656 notify(m_clients[i].url, msg);
1581 1657  
1582   - } // endelse: metadata
  1658 + } // endelse: metadata
1583 1659  
1584 1660 } // endif: method was requested one
1585 1661  
... ... @@ -1590,13 +1666,135 @@ void GVOHub::send_notifications(const std::string&amp; method,
1590 1666 // Return
1591 1667 return;
1592 1668 }
  1669 +/***********************************************************************//**
  1670 + * @brief Send notifications
  1671 + *
  1672 + * @param[in] method Name of the method
  1673 + * @param[in] client Reference of the client
  1674 + * @param[in] xml message sent by the client
  1675 + *
  1676 + * Send notifications to all registered clients that request so.
  1677 + ***************************************************************************/
  1678 +void GVOHub::send_notifications(const std::string& method,
  1679 + const std::string& client,
  1680 + const GXml& xml)
  1681 +{
  1682 + // Debug: dump information to console
  1683 + #if defined(G_CONSOLE_DUMP)
  1684 + std::cout << "GVOHub::send_notifications 2nd form" << std::endl;
  1685 + std::cout << "GVOHub::send_notifications "+method << std::endl;
  1686 + #endif
  1687 +
  1688 + // Loop over all clients
  1689 + for (int i = 0; i < m_clients.size(); ++i) {
  1690 +
  1691 + // Loop over all methods
  1692 + for (int j = 0; j < m_clients[i].subscriptions.size(); ++j) {
  1693 +
  1694 + // Continue only if method matches
  1695 + if (method == m_clients[i].subscriptions[j]) {
  1696 +
  1697 + // Declare notification
  1698 + std::string msg = "";
  1699 +
  1700 + // Image loading
  1701 + if (method == "image.load.fits") {
  1702 +
  1703 + // Debug: dump information to console
  1704 + #if defined(G_CONSOLE_DUMP)
  1705 + std::cout << "GVOHub:: Preparing broadcast message" << std::endl;
  1706 + #endif
  1707 +
  1708 + // Declare value
  1709 + std::string value = "";
  1710 +
  1711 + // Search for value of specified member
  1712 + const GXmlNode* node = xml.element("methodCall > params > param[2] > value > struct > member > value > struct");
  1713 + #if defined(G_CONSOLE_DUMP)
  1714 + std::cout << "Searching url value" << std::endl;
  1715 + #endif
  1716 + if (node != NULL) {
  1717 + #if defined(G_CONSOLE_DUMP)
  1718 + std::cout << "Node found" << std::endl;
  1719 + #endif
  1720 + int num = node->elements("member");
  1721 + for (int i = 0; i < num; ++i) {
  1722 + const GXmlNode* member = node->element("member", i);
  1723 + std::string one_name;
  1724 + std::string one_value;
  1725 + get_name_value_pair(member, one_name, one_value);
  1726 + #if defined(G_CONSOLE_DUMP)
  1727 + std::cout << "name: "+one_name << std::endl;
  1728 + #endif
  1729 + if (one_name == "url") {
  1730 + value = one_value;
  1731 + break;
  1732 + }
  1733 + }
  1734 + } else {
  1735 + #if defined(G_CONSOLE_DUMP)
  1736 + std::cout << "Node not found" << std::endl;
  1737 + #endif
  1738 + }
  1739 +
  1740 + // Set response for image.load.fits
  1741 + msg.append("<?xml version=\"1.0\"?>\n");
  1742 + msg.append("<methodCall>\n");
  1743 + msg.append("<methodName>samp.client.receiveNotification</methodName>\n");
  1744 + msg.append("<params>\n");
  1745 + msg.append(" <param><value>");
  1746 + msg.append(m_clients[i].private_key);
  1747 + msg.append("</value></param>\n");
  1748 + msg.append(" <param><value>");
  1749 + msg.append(m_hub_id);
  1750 + msg.append("</value></param>\n");
  1751 + msg.append(" <param><value><struct>\n");
  1752 + msg.append(" <member>\n");
  1753 + msg.append(" <name>samp.mtype</name>\n");
  1754 + msg.append(" <value>image.load.fits</value>\n");
  1755 + msg.append(" </member>\n");
  1756 + msg.append(" <member>\n");
  1757 + msg.append(" <name>samp.params</name>\n");
  1758 + msg.append(" <value><struct>\n");
  1759 + msg.append(" <member>\n");
  1760 + msg.append(" <name>name</name>\n");
  1761 + msg.append(" <value>Gammalib_shared_fits</value>\n");
  1762 + msg.append(" </member>\n");
  1763 + msg.append(" <member>\n");
  1764 + msg.append(" <name>image-id</name>\n");
  1765 + msg.append(" <value>Gammalib_shared_fits_id</value>\n");
  1766 + msg.append(" </member>\n");
  1767 + msg.append(" <member>\n");
  1768 + msg.append(" <name>url</name>\n");
  1769 + msg.append(" <value>"+value+"</value>\n");
  1770 + msg.append(" </member>\n");
  1771 + msg.append(" </struct></value>\n");
  1772 + msg.append(" </member>\n");
  1773 + msg.append(" </struct></value></param>\n");
  1774 + msg.append("</params>\n");
  1775 + msg.append("</methodCall>\n");
  1776 + #if defined(G_CONSOLE_DUMP)
  1777 + std::cout << msg << std::endl;
  1778 + #endif
1593 1779  
  1780 + // Post notification
  1781 + notify(m_clients[i].url, msg);
  1782 +
  1783 + }
  1784 + } // endif: method was requested one
  1785 +
  1786 + } // endfor: looped over all methods
  1787 +
  1788 + } // endfor: looped over all clients
  1789 +
  1790 + // Return
  1791 + return;
  1792 +}
1594 1793  
1595 1794 /***********************************************************************//**
1596   - * @brief Create the lockfile
  1795 + * @brief Creates the lockfile, fill it
1597 1796 *
1598   - * Creates the SAMP lockfile and fill it with information. Implements IVOA
1599   - * standard REC-SAMP-1.3-20120411.
  1797 + * Implements IVOA standard REC-SAMP-1.3-20120411.
1600 1798 ***************************************************************************/
1601 1799 void GVOHub::create_samp_file(void) const
1602 1800 {
... ... @@ -1613,7 +1811,7 @@ void GVOHub::create_samp_file(void) const
1613 1811 fprintf(fptr, "# SAMP lockfile\n");
1614 1812 fprintf(fptr, "# Required keys:\n");
1615 1813 fprintf(fptr, "samp.secret=%s\n", m_secret.c_str());
1616   - fprintf(fptr, "samp.hub.xmlrpc.url=%s\n", hub_url().c_str());
  1814 + fprintf(fptr, "samp.hub.xmlrpc.url=%s\n", m_hub_url.c_str());
1617 1815 fprintf(fptr, "samp.profile.version=%s\n", m_version.c_str());
1618 1816 fprintf(fptr, "# Info stored by hub for some private reason:\n");
1619 1817 fprintf(fptr, "gammalib.hubid=%s\n", m_hub_id.c_str());
... ... @@ -1629,87 +1827,6 @@ void GVOHub::create_samp_file(void) const
1629 1827  
1630 1828  
1631 1829 /***********************************************************************//**
1632   - * @brief Delete the lockfile
1633   - *
1634   - * Deletes the SAMP lockfile on disk.
1635   - ***************************************************************************/
1636   -void GVOHub::delete_samp_file(void) const
1637   -{
1638   - // Get lockfile URL
1639   - std::string lockurl = get_hub_lockfile();
1640   -
1641   - // Delete lockfile
1642   - std::remove(lockurl.c_str());
1643   -
1644   - // Return
1645   - return;
1646   -}
1647   -
1648   -
1649   -/***********************************************************************//**
1650   - * @brief Get Hub socket
1651   - *
1652   - * @return Hub socket (-1 if no socket was found).
1653   - *
1654   - * Returns Hub socket. Starting from an initial port of 2526 the method
1655   - * searches for the next free port and binds it to a socket.
1656   - ***************************************************************************/
1657   -int GVOHub::get_socket(void)
1658   -{
1659   - // Initialise socket, port and socket address structure
1660   - int sock = -1;
1661   - int port = 2526;
1662   - struct sockaddr_in serv_addr;
1663   -
1664   - // Loop over 100 ports at most
1665   - for (int i = 0; i < 100; ++i) {
1666   -
1667   - // Clean TCP/IP structure
1668   - std::memset(&serv_addr, 0, sizeof(serv_addr));
1669   -
1670   - // Set TCP/IP structure
1671   - serv_addr.sin_family = AF_INET;
1672   - serv_addr.sin_addr.s_addr = inet_addr(m_hub_host.c_str());
1673   - serv_addr.sin_port = htons(port);
1674   -
1675   - // Create Hub socket
1676   - sock = socket(AF_INET, SOCK_STREAM, 0);
1677   -
1678   - // Creation of hub main socket
1679   - if (sock < 0) {
1680   - std::string msg = "Unable to create Hub socket. Errno="+
1681   - gammalib::str(errno);
1682   - throw GException::runtime_error(G_START_SOCKET, msg);
1683   - }
1684   -
1685   - // Now bind socket to the address and port
1686   - if (bind(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
1687   - if (errno == EADDRINUSE) {
1688   - port++;
1689   - close(sock);
1690   - }
1691   - else {
1692   - std::string msg = "Unable to bind Hub socket to address "+
1693   - m_hub_host+":"+gammalib::str(port)+
1694   - ". Errno="+gammalib::str(errno);
1695   - throw GException::runtime_error(G_START_HUB, msg);
1696   - }
1697   - }
1698   - else {
1699   - break;
1700   - }
1701   -
1702   - } // endfor: looped over ports
1703   -
1704   - // Store port as string
1705   - m_hub_port = gammalib::str(port);
1706   -
1707   - // Return socket
1708   - return sock;
1709   -}
1710   -
1711   -
1712   -/***********************************************************************//**
1713 1830 * @brief Post string content to client
1714 1831 *
1715 1832 * @param[in] content String content to post.
... ... @@ -1948,24 +2065,6 @@ void GVOHub::notify(const std::string&amp; url,
1948 2065 }
1949 2066 } while (!done);
1950 2067  
1951   - /*
1952   - // Declare response
1953   - std::string response = "";
1954   -
1955   - // Read buffer until it is empty
1956   - char buffer[1001];
1957   - int timeout = 1000; // Initial timeout is 1 sec
1958   - int n = 0;
1959   - do {
1960   - n = gammalib::recv(socket, buffer, 1000, 0, timeout);
1961   - if (n > 0) {
1962   - buffer[n+1] = '\0';
1963   - response.append(std::string(buffer));
1964   - }
1965   - timeout = 10; // The timeout now is 0.01 sec
1966   - } while (n > 0);
1967   - */
1968   -
1969 2068 // Close socket
1970 2069 close(socket);
1971 2070  
... ... @@ -1994,21 +2093,61 @@ std::string GVOHub::random_string(const size_t&amp; length) const
1994 2093 // Return string
1995 2094 return str;
1996 2095 }
  2096 +/***********************************************************************//**
  2097 + * @brief Extract mtype from XML request
  2098 + *
  2099 + * @param[in] xml XML message sent by client.
  2100 + *
  2101 + * Extracts the mtype identifying calling message from the XML request.
  2102 + ***************************************************************************/
  2103 +std::string GVOHub::get_mtype(const GXml& xml) const
  2104 +{
  2105 + // Header
  2106 + #if defined(G_CONSOLE_DUMP)
  2107 + std::cout << "GVOHub::get_mtype" << std::endl;
  2108 + #endif
1997 2109  
  2110 + // Initialise response
  2111 + std::string client_key = "";
  2112 +
  2113 + // Get the client's private key
  2114 + const GXmlNode* node = xml.element("methodCall > params > param > value");
  2115 + if (node != NULL) {
  2116 + const GXmlText* text = static_cast<const GXmlText*>((*node)[0]);
  2117 + if (text != NULL) {
  2118 + client_key = text->text();
  2119 + }
  2120 + }
1998 2121  
  2122 + // Return key
  2123 + return client_key;
  2124 +}
1999 2125 /***********************************************************************//**
2000   - * @brief Return Hub URL
  2126 + * @brief Extract client destination from XML request
2001 2127 *
2002   - * @return Hub URL.
  2128 + * @param[in] xml XML message sent by client.
2003 2129 *
2004   - * Returns the XML-RPC endpoint for communication with the hub.
  2130 + * Extracts identifier of destination client from the XML request.
2005 2131 ***************************************************************************/
2006   -std::string GVOHub::hub_url(void) const
  2132 +std::string GVOHub::get_destination(const GXml& xml) const
2007 2133 {
2008   - // Set Hub URL
2009   - std::string hub_url = "http://"+m_hub_host+":"+m_hub_port+"/"+m_hub_path;
  2134 + // Header
  2135 + #if defined(G_CONSOLE_DUMP)
  2136 + std::cout << "GVOHub::get_mtype" << std::endl;
  2137 + #endif
2010 2138  
2011   - // Return Hub URL
2012   - return (hub_url);
2013   -}
  2139 + // Initialise response
  2140 + std::string client_key = "";
  2141 +
  2142 + // Get the client's private key
  2143 + const GXmlNode* node = xml.element("methodCall > params > param > value");
  2144 + if (node != NULL) {
  2145 + const GXmlText* text = static_cast<const GXmlText*>((*node)[0]);
  2146 + if (text != NULL) {
  2147 + client_key = text->text();
  2148 + }
  2149 + }
2014 2150  
  2151 + // Return key
  2152 + return client_key;
  2153 +}
... ...