Commit def74ccbcb555ecdaf5b55d714c43aed9b7f5282

Authored by Jürgen Knödlseder
1 parent b76e4481

Put back code in GVOHub that got erased during the last code merge.

include/GVOHub.hpp
@@ -45,8 +45,8 @@ class GXmlNode; @@ -45,8 +45,8 @@ class GXmlNode;
45 * 45 *
46 * @brief VO SAMP Hub class 46 * @brief VO SAMP Hub class
47 * 47 *
48 - * This class implements a SAMP hub for exchanges through VO-compatible  
49 - * applications. 48 + * This class implements a SAMP hub to support the interoperability of
  49 + * Virtual Observatory applications.
50 ***************************************************************************/ 50 ***************************************************************************/
51 class GVOHub : public GBase { 51 class GVOHub : public GBase {
52 52
@@ -65,7 +65,6 @@ public: @@ -65,7 +65,6 @@ public:
65 std::string classname(void) const; 65 std::string classname(void) const;
66 void start(void); 66 void start(void);
67 std::string print(const GChatter& chatter = NORMAL) const; 67 std::string print(const GChatter& chatter = NORMAL) const;
68 -  
69 68
70 protected: 69 protected:
71 // Protected methods 70 // Protected methods
@@ -108,7 +107,6 @@ protected: @@ -108,7 +107,6 @@ protected:
108 std::string get_callback_url(const GXml& xml) const; 107 std::string get_callback_url(const GXml& xml) const;
109 std::string get_hub_lockfile(void) const; 108 std::string get_hub_lockfile(void) const;
110 std::string get_mtype(const GXml& xml) const; 109 std::string get_mtype(const GXml& xml) const;
111 - std::string get_destination(const GXml& xml) const;  
112 110
113 // Client structure 111 // Client structure
114 struct client { 112 struct client {
@@ -128,6 +126,8 @@ protected: @@ -128,6 +126,8 @@ protected:
128 126
129 // Low-level methods 127 // Low-level methods
130 void create_samp_file(void) const; 128 void create_samp_file(void) const;
  129 + void delete_samp_file(void) const;
  130 + int get_socket(void);
131 void post_samp_ok(const socklen_t& sock) const; 131 void post_samp_ok(const socklen_t& sock) const;
132 void post_samp_void(const socklen_t& sock) const; 132 void post_samp_void(const socklen_t& sock) const;
133 void post_string(const std::string& content, 133 void post_string(const std::string& content,
@@ -143,16 +143,16 @@ protected: @@ -143,16 +143,16 @@ protected:
143 void notify_image_load(const client& client, 143 void notify_image_load(const client& client,
144 const GXml& xml); 144 const GXml& xml);
145 std::string random_string(const size_t& length) const; 145 std::string random_string(const size_t& length) const;
  146 + std::string hub_url(void) const;
146 147
147 // Protected members 148 // Protected members
148 std::string m_secret; //!< Secret Hub key 149 std::string m_secret; //!< Secret Hub key
149 - std::string m_hub_url; //!< The XML-RPC endpoint for communication with the hub  
150 std::string m_hub_host; //!< Hub host 150 std::string m_hub_host; //!< Hub host
151 std::string m_hub_port; //!< Hub port 151 std::string m_hub_port; //!< Hub port
152 std::string m_hub_path; //!< Hub path 152 std::string m_hub_path; //!< Hub path
153 std::string m_version; //!< The version of the SAMP Standard Profile implemented by the hub 153 std::string m_version; //!< The version of the SAMP Standard Profile implemented by the hub
154 std::string m_hub_id; //!< Hub identifier used by the hub when it sends message itself rather than forwarding from others 154 std::string m_hub_id; //!< Hub identifier used by the hub when it sends message itself rather than forwarding from others
155 - socklen_t m_socket; //!< Hub socket 155 + int m_socket; //!< Hub socket
156 bool m_shutdown; //!< Shutdown request 156 bool m_shutdown; //!< Shutdown request
157 std::vector<client> m_clients; //!< Clients 157 std::vector<client> m_clients; //!< Clients
158 }; 158 };
src/vo/GVOHub.cpp
@@ -49,6 +49,7 @@ @@ -49,6 +49,7 @@
49 49
50 /* __ Method name definitions ____________________________________________ */ 50 /* __ Method name definitions ____________________________________________ */
51 #define G_START_HUB "GVOHub::start_hub()" 51 #define G_START_HUB "GVOHub::start_hub()"
  52 +#define G_GET_SOCKET "GVOHub::get_socket()"
52 53
53 /* __ Macros _____________________________________________________________ */ 54 /* __ Macros _____________________________________________________________ */
54 55
@@ -182,9 +183,6 @@ GVOHub* GVOHub::clone(void) const @@ -182,9 +183,6 @@ GVOHub* GVOHub::clone(void) const
182 ***************************************************************************/ 183 ***************************************************************************/
183 void GVOHub::start(void) 184 void GVOHub::start(void)
184 { 185 {
185 - // Create SAMP file  
186 - create_samp_file();  
187 -  
188 // Start Hub 186 // Start Hub
189 start_hub(); 187 start_hub();
190 188
@@ -213,7 +211,7 @@ std::string GVOHub::print(const GChatter&amp; chatter) const @@ -213,7 +211,7 @@ std::string GVOHub::print(const GChatter&amp; chatter) const
213 // Append Hub information 211 // Append Hub information
214 result.append("\n"+gammalib::parformat("Hub identifier")+m_hub_id); 212 result.append("\n"+gammalib::parformat("Hub identifier")+m_hub_id);
215 result.append("\n"+gammalib::parformat("Hub key")+m_secret); 213 result.append("\n"+gammalib::parformat("Hub key")+m_secret);
216 - result.append("\n"+gammalib::parformat("Hub URL")+m_hub_url); 214 + result.append("\n"+gammalib::parformat("Hub URL")+hub_url());
217 result.append("\n"+gammalib::parformat("Hub host")+m_hub_host); 215 result.append("\n"+gammalib::parformat("Hub host")+m_hub_host);
218 result.append("\n"+gammalib::parformat("Hub port")+m_hub_port); 216 result.append("\n"+gammalib::parformat("Hub port")+m_hub_port);
219 result.append("\n"+gammalib::parformat("Hub path")+m_hub_path); 217 result.append("\n"+gammalib::parformat("Hub path")+m_hub_path);
@@ -243,7 +241,6 @@ void GVOHub::init_members(void) @@ -243,7 +241,6 @@ void GVOHub::init_members(void)
243 m_hub_host = "127.0.0.1"; 241 m_hub_host = "127.0.0.1";
244 m_hub_port = "2526"; 242 m_hub_port = "2526";
245 m_hub_path = "xmlrpc"; 243 m_hub_path = "xmlrpc";
246 - m_hub_url = "http://"+m_hub_host+":"+m_hub_port+"/"+m_hub_path;  
247 m_version = "1.3"; 244 m_version = "1.3";
248 m_hub_id = "gammalib_hub"; 245 m_hub_id = "gammalib_hub";
249 m_socket = -1; // Signals no socket 246 m_socket = -1; // Signals no socket
@@ -264,7 +261,6 @@ void GVOHub::copy_members(const GVOHub&amp; hub) @@ -264,7 +261,6 @@ void GVOHub::copy_members(const GVOHub&amp; hub)
264 { 261 {
265 // Copy members 262 // Copy members
266 m_secret = hub.m_secret; 263 m_secret = hub.m_secret;
267 - m_hub_url = hub.m_hub_url;  
268 m_hub_host = hub.m_hub_host; 264 m_hub_host = hub.m_hub_host;
269 m_hub_port = hub.m_hub_port; 265 m_hub_port = hub.m_hub_port;
270 m_hub_path = hub.m_hub_path; 266 m_hub_path = hub.m_hub_path;
@@ -291,8 +287,7 @@ void GVOHub::free_members(void) @@ -291,8 +287,7 @@ void GVOHub::free_members(void)
291 } 287 }
292 288
293 // Remove lockfile 289 // Remove lockfile
294 - std::string lockurl = get_hub_lockfile();  
295 - std::remove(lockurl.c_str()); 290 + delete_samp_file();
296 291
297 // Return 292 // Return
298 return; 293 return;
@@ -309,46 +304,13 @@ void GVOHub::free_members(void) @@ -309,46 +304,13 @@ void GVOHub::free_members(void)
309 ***************************************************************************/ 304 ***************************************************************************/
310 void GVOHub::start_hub(void) 305 void GVOHub::start_hub(void)
311 { 306 {
312 - // Prepare TCP/IP structure  
313 - struct sockaddr_in serv_addr;  
314 - std::memset(&serv_addr, 0, sizeof(serv_addr));  
315 - serv_addr.sin_family = AF_INET;  
316 - serv_addr.sin_addr.s_addr = inet_addr(m_hub_host.c_str());  
317 - serv_addr.sin_port = htons(gammalib::toint(m_hub_port));  
318 -  
319 - // Create Hub socket  
320 - m_socket = socket(AF_INET, SOCK_STREAM, 0);  
321 -  
322 - // Creation of hub main socket  
323 - if (m_socket < 0) {  
324 - std::string msg = "Unable to create Hub socket. Errno="+  
325 - gammalib::str(errno);  
326 - throw GException::runtime_error(G_START_HUB, msg);  
327 - }  
328 -  
329 - // Set hub main socket to allow multiple connections  
330 - int opt = 1;  
331 - if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0) {  
332 - std::string msg = "Unable to set Hub socket to multiple connections."  
333 - " Errno="+gammalib::str(errno);  
334 - throw GException::runtime_error(G_START_HUB, msg);  
335 - }  
336 - #ifdef SO_REUSEPORT  
337 - if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEPORT, (char*)&opt, sizeof(opt)) < 0) {  
338 - std::string msg = "Unable to set Hub socket to multiple connections."  
339 - " Errno="+gammalib::str(errno);  
340 - throw GException::runtime_error(G_START_HUB, msg);  
341 - }  
342 - #endif  
343 -  
344 - // Server socket is opened. Now, bind it to the port, with family etc.  
345 - if (bind(m_socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {  
346 - std::string msg = "Unable to bind Hub socket to server socket. Errno="+  
347 - gammalib::str(errno);  
348 - throw GException::runtime_error(G_START_HUB, msg);  
349 - } 307 + // Get socket
  308 + m_socket = get_socket();
  309 +
  310 + // Create SAMP file
  311 + create_samp_file();
350 312
351 - // Now start listening for the clients: 5 requests simultaneously pending 313 + // Start listening for the clients: 5 requests simultaneously pending
352 // at maximum 314 // at maximum
353 if (listen(m_socket, 5) < 0) { 315 if (listen(m_socket, 5) < 0) {
354 std::string msg = "Unable to start listening on Hub socket. Errno="+ 316 std::string msg = "Unable to start listening on Hub socket. Errno="+
@@ -364,7 +326,7 @@ void GVOHub::start_hub(void) @@ -364,7 +326,7 @@ void GVOHub::start_hub(void)
364 while (1) { 326 while (1) {
365 327
366 // Accept connection from the client 328 // Accept connection from the client
367 - socklen_t socket = accept(m_socket, (struct sockaddr *)&cli_addr, &clilen); 329 + int socket = accept(m_socket, (struct sockaddr *)&cli_addr, &clilen);
368 if (socket < 0) { 330 if (socket < 0) {
369 std::string msg = "Client connection to socket not accepted."; 331 std::string msg = "Client connection to socket not accepted.";
370 throw GException::runtime_error(G_START_HUB, msg); 332 throw GException::runtime_error(G_START_HUB, msg);
@@ -388,6 +350,9 @@ void GVOHub::start_hub(void) @@ -388,6 +350,9 @@ void GVOHub::start_hub(void)
388 close(m_socket); 350 close(m_socket);
389 m_socket = -1; 351 m_socket = -1;
390 352
  353 + // Delete SAMP file
  354 + delete_samp_file();
  355 +
391 // Return 356 // Return
392 return; 357 return;
393 } 358 }
@@ -433,12 +398,11 @@ void GVOHub::handle_request(const socklen_t&amp; sock) @@ -433,12 +398,11 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
433 398
434 // Extract response into an XML object 399 // Extract response into an XML object
435 GXml xml; 400 GXml xml;
436 -  
437 size_t start = message.find("<?xml"); 401 size_t start = message.find("<?xml");
438 if (start != std::string::npos) { 402 if (start != std::string::npos) {
439 xml = GXml(message.substr(start, std::string::npos)); 403 xml = GXml(message.substr(start, std::string::npos));
440 } 404 }
441 - 405 +
442 // Get methodName value 406 // Get methodName value
443 std::string method_called; 407 std::string method_called;
444 const GXmlNode* node = xml.element("methodCall > methodName"); 408 const GXmlNode* node = xml.element("methodCall > methodName");
@@ -486,9 +450,6 @@ void GVOHub::handle_request(const socklen_t&amp; sock) @@ -486,9 +450,6 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
486 else if (method_called.compare("samp.hub.getMetadata") == 0) { 450 else if (method_called.compare("samp.hub.getMetadata") == 0) {
487 request_get_metadata(xml, sock); 451 request_get_metadata(xml, sock);
488 } 452 }
489 - else if (method_called.compare("table.load.votable") == 0) {  
490 - request_ping(sock);  
491 - }  
492 else if (method_called.compare("samp.hub.notify") == 0) { 453 else if (method_called.compare("samp.hub.notify") == 0) {
493 request_ping(sock); 454 request_ping(sock);
494 } 455 }
@@ -604,7 +565,7 @@ void GVOHub::request_register(const GXml&amp; xml, const socklen_t&amp; sock) @@ -604,7 +565,7 @@ void GVOHub::request_register(const GXml&amp; xml, const socklen_t&amp; sock)
604 response.append(" </member>\n"); 565 response.append(" </member>\n");
605 response.append(" <member>\n"); 566 response.append(" <member>\n");
606 response.append(" <name>samp.url-translator</name>\n"); 567 response.append(" <name>samp.url-translator</name>\n");
607 - response.append(" <value>"+m_hub_url+"</value>\n"); 568 + response.append(" <value>"+hub_url()+"</value>\n");
608 response.append(" </member>\n"); 569 response.append(" </member>\n");
609 response.append(" </struct></value></param>\n"); 570 response.append(" </struct></value></param>\n");
610 response.append("</params>\n"); 571 response.append("</params>\n");
@@ -816,9 +777,6 @@ void GVOHub::request_set_xml_rpc_callback(const GXml&amp; xml, @@ -816,9 +777,6 @@ void GVOHub::request_set_xml_rpc_callback(const GXml&amp; xml,
816 // Continue only if index is valid 777 // Continue only if index is valid
817 if (i != -1) { 778 if (i != -1) {
818 779
819 - // Get callback URL  
820 - std::string client_url = get_callback_url(xml);  
821 -  
822 // Set callback URL 780 // Set callback URL
823 m_clients[i].url = get_callback_url(xml); 781 m_clients[i].url = get_callback_url(xml);
824 782
@@ -947,6 +905,7 @@ void GVOHub::request_get_registered_clients(const GXml&amp; xml, const socklen_t&amp; so @@ -947,6 +905,7 @@ void GVOHub::request_get_registered_clients(const GXml&amp; xml, const socklen_t&amp; so
947 905
948 // Declare message 906 // Declare message
949 std::string msg = ""; 907 std::string msg = "";
  908 +
950 // Set response 909 // Set response
951 msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 910 msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
952 msg.append("<methodResponse>\n"); 911 msg.append("<methodResponse>\n");
@@ -967,12 +926,12 @@ void GVOHub::request_get_registered_clients(const GXml&amp; xml, const socklen_t&amp; so @@ -967,12 +926,12 @@ void GVOHub::request_get_registered_clients(const GXml&amp; xml, const socklen_t&amp; so
967 msg.append(" </data></array></value></param>\n"); 926 msg.append(" </data></array></value></param>\n");
968 msg.append("</params>\n"); 927 msg.append("</params>\n");
969 msg.append("</methodResponse>\n"); 928 msg.append("</methodResponse>\n");
  929 +
970 // Post response 930 // Post response
971 post_string(msg, sock); 931 post_string(msg, sock);
972 932
973 // Return 933 // Return
974 return; 934 return;
975 -  
976 } 935 }
977 936
978 937
@@ -1530,9 +1489,10 @@ std::string GVOHub::get_hub_lockfile(void) const @@ -1530,9 +1489,10 @@ std::string GVOHub::get_hub_lockfile(void) const
1530 1489
1531 1490
1532 /***********************************************************************//** 1491 /***********************************************************************//**
1533 - * @brief Creates the lockfile, fill it 1492 + * @brief Create the lockfile
1534 * 1493 *
1535 - * Implements IVOA standard REC-SAMP-1.3-20120411. 1494 + * Creates the SAMP lockfile and fill it with information. Implements IVOA
  1495 + * standard REC-SAMP-1.3-20120411.
1536 ***************************************************************************/ 1496 ***************************************************************************/
1537 void GVOHub::create_samp_file(void) const 1497 void GVOHub::create_samp_file(void) const
1538 { 1498 {
@@ -1549,7 +1509,7 @@ void GVOHub::create_samp_file(void) const @@ -1549,7 +1509,7 @@ void GVOHub::create_samp_file(void) const
1549 fprintf(fptr, "# SAMP lockfile\n"); 1509 fprintf(fptr, "# SAMP lockfile\n");
1550 fprintf(fptr, "# Required keys:\n"); 1510 fprintf(fptr, "# Required keys:\n");
1551 fprintf(fptr, "samp.secret=%s\n", m_secret.c_str()); 1511 fprintf(fptr, "samp.secret=%s\n", m_secret.c_str());
1552 - fprintf(fptr, "samp.hub.xmlrpc.url=%s\n", m_hub_url.c_str()); 1512 + fprintf(fptr, "samp.hub.xmlrpc.url=%s\n", hub_url().c_str());
1553 fprintf(fptr, "samp.profile.version=%s\n", m_version.c_str()); 1513 fprintf(fptr, "samp.profile.version=%s\n", m_version.c_str());
1554 fprintf(fptr, "# Info stored by hub for some private reason:\n"); 1514 fprintf(fptr, "# Info stored by hub for some private reason:\n");
1555 fprintf(fptr, "gammalib.hubid=%s\n", m_hub_id.c_str()); 1515 fprintf(fptr, "gammalib.hubid=%s\n", m_hub_id.c_str());
@@ -1565,6 +1525,87 @@ void GVOHub::create_samp_file(void) const @@ -1565,6 +1525,87 @@ void GVOHub::create_samp_file(void) const
1565 1525
1566 1526
1567 /***********************************************************************//** 1527 /***********************************************************************//**
  1528 + * @brief Delete the lockfile
  1529 + *
  1530 + * Deletes the SAMP lockfile on disk.
  1531 + ***************************************************************************/
  1532 +void GVOHub::delete_samp_file(void) const
  1533 +{
  1534 + // Get lockfile URL
  1535 + std::string lockurl = get_hub_lockfile();
  1536 +
  1537 + // Delete lockfile
  1538 + std::remove(lockurl.c_str());
  1539 +
  1540 + // Return
  1541 + return;
  1542 +}
  1543 +
  1544 +
  1545 +/***********************************************************************//**
  1546 + * @brief Get Hub socket
  1547 + *
  1548 + * @return Hub socket (-1 if no socket was found).
  1549 + *
  1550 + * Returns Hub socket. Starting from an initial port of 2526 the method
  1551 + * searches for the next free port and binds it to a socket.
  1552 + ***************************************************************************/
  1553 +int GVOHub::get_socket(void)
  1554 +{
  1555 + // Initialise socket, port and socket address structure
  1556 + int sock = -1;
  1557 + int port = 2526;
  1558 + struct sockaddr_in serv_addr;
  1559 +
  1560 + // Loop over 100 ports at most
  1561 + for (int i = 0; i < 100; ++i) {
  1562 +
  1563 + // Clean TCP/IP structure
  1564 + std::memset(&serv_addr, 0, sizeof(serv_addr));
  1565 +
  1566 + // Set TCP/IP structure
  1567 + serv_addr.sin_family = AF_INET;
  1568 + serv_addr.sin_addr.s_addr = inet_addr(m_hub_host.c_str());
  1569 + serv_addr.sin_port = htons(port);
  1570 +
  1571 + // Create Hub socket
  1572 + sock = socket(AF_INET, SOCK_STREAM, 0);
  1573 +
  1574 + // Creation of hub main socket
  1575 + if (sock < 0) {
  1576 + std::string msg = "Unable to create Hub socket. Errno="+
  1577 + gammalib::str(errno);
  1578 + throw GException::runtime_error(G_GET_SOCKET, msg);
  1579 + }
  1580 +
  1581 + // Now bind socket to the address and port
  1582 + if (bind(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
  1583 + if (errno == EADDRINUSE) {
  1584 + port++;
  1585 + close(sock);
  1586 + }
  1587 + else {
  1588 + std::string msg = "Unable to bind Hub socket to address "+
  1589 + m_hub_host+":"+gammalib::str(port)+
  1590 + ". Errno="+gammalib::str(errno);
  1591 + throw GException::runtime_error(G_GET_SOCKET, msg);
  1592 + }
  1593 + }
  1594 + else {
  1595 + break;
  1596 + }
  1597 +
  1598 + } // endfor: looped over ports
  1599 +
  1600 + // Store port as string
  1601 + m_hub_port = gammalib::str(port);
  1602 +
  1603 + // Return socket
  1604 + return sock;
  1605 +}
  1606 +
  1607 +
  1608 +/***********************************************************************//**
1568 * @brief Post string content to client 1609 * @brief Post string content to client
1569 * 1610 *
1570 * @param[in] content String content to post. 1611 * @param[in] content String content to post.
@@ -2083,7 +2124,7 @@ std::string GVOHub::random_string(const size_t&amp; length) const @@ -2083,7 +2124,7 @@ std::string GVOHub::random_string(const size_t&amp; length) const
2083 int pos; 2124 int pos;
2084 while(str.size() != length) { 2125 while(str.size() != length) {
2085 pos = ((rand() % (str.size() - 1))); 2126 pos = ((rand() % (str.size() - 1)));
2086 - str.erase (pos, 1); 2127 + str.erase(pos, 1);
2087 } 2128 }
2088 2129
2089 // Return string 2130 // Return string
@@ -2123,31 +2164,17 @@ std::string GVOHub::get_mtype(const GXml&amp; xml) const @@ -2123,31 +2164,17 @@ std::string GVOHub::get_mtype(const GXml&amp; xml) const
2123 2164
2124 2165
2125 /***********************************************************************//** 2166 /***********************************************************************//**
2126 - * @brief Extract client destination from XML request 2167 + * @brief Return Hub URL
2127 * 2168 *
2128 - * @param[in] xml XML message sent by client. 2169 + * @return Hub URL.
2129 * 2170 *
2130 - * Extracts identifier of destination client from the XML request. 2171 + * Returns the XML-RPC endpoint for communication with the hub.
2131 ***************************************************************************/ 2172 ***************************************************************************/
2132 -std::string GVOHub::get_destination(const GXml& xml) const 2173 +std::string GVOHub::hub_url(void) const
2133 { 2174 {
2134 - // Header  
2135 - #if defined(G_CONSOLE_DUMP)  
2136 - std::cout << "GVOHub::get_destination" << std::endl;  
2137 - #endif  
2138 -  
2139 - // Initialise response  
2140 - std::string client_key = ""; 2175 + // Set Hub URL
  2176 + std::string hub_url = "http://"+m_hub_host+":"+m_hub_port+"/"+m_hub_path;
2141 2177
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 - }  
2150 -  
2151 - // Return key  
2152 - return client_key; 2178 + // Return Hub URL
  2179 + return (hub_url);
2153 } 2180 }