From b7e72f8377b98b38707bac5ad60bb7dfa48368cf Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Tue, 23 Feb 2016 22:17:59 +0100 Subject: [PATCH] Refactor code of GVOHub a bit. --- ChangeLog | 3 ++- NEWS | 6 ++++-- include/GVOClient.hpp | 11 +++++++---- include/GVOHub.hpp | 64 ++++++++++++++++++++++++++++++++++++---------------------------- src/vo/GVOClient.cpp | 36 ++++++++++++++++++++++++++++++------ src/vo/GVOHub.cpp | 776 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 6 files changed, 467 insertions(+), 429 deletions(-) diff --git a/ChangeLog b/ChangeLog index 584ec67..bb5c331 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,9 @@ -2016-02-18 Juergen Knoedlseder +2016-02-23 Juergen Knoedlseder * Version 1.1.0 released ========================= + Add GVOClient::publish() method to publish a FITS HDU (#1231) Handle FITS extensions in GSkyMap load() and save() methods (#1695) Restrict Monte Carlo simulations in GModelSpatialDiffuseConst to simulation cone (#1674) Use default GTime in GModelSpectral eval() and eval_gradients() methods (#1672) diff --git a/NEWS b/NEWS index b39eabc..2b25f34 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ New Features and Important Changes in GammaLib 1.1.0 Author(s) : Juergen Knoedlseder -18 February 2016 +23 February 2016 1. Introduction @@ -178,7 +178,9 @@ None 15. VO module ------------- -None +A GVOClient::publish() method was added that allows publishing of a FITS +image to the Hub. The FITS image will be saved into a temporary storage +location and the Hub will be informed that an image is available. 16. Xspec module diff --git a/include/GVOClient.hpp b/include/GVOClient.hpp index 835c3cd..260250c 100644 --- a/include/GVOClient.hpp +++ b/include/GVOClient.hpp @@ -1,7 +1,7 @@ /*************************************************************************** * GVOClient.hpp - VO client class * * ----------------------------------------------------------------------- * - * copyright (C) 2013-2015 by Juergen Knoedlseder * + * copyright (C) 2013-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -30,9 +30,12 @@ /* __ Includes ___________________________________________________________ */ #include #include "GBase.hpp" -#include "GXml.hpp" -#include "GXmlNode.hpp" -#include "GFits.hpp" + +/* __ Forward declarations _______________________________________________ */ +class GFitsHDU; +class GXml; +class GXmlNode; + /***********************************************************************//** * @class GVOClient diff --git a/include/GVOHub.hpp b/include/GVOHub.hpp index cd75487..da7ac1c 100644 --- a/include/GVOHub.hpp +++ b/include/GVOHub.hpp @@ -1,7 +1,7 @@ /*************************************************************************** * GVOHub.hpp - VO SAMP Hub class * * ----------------------------------------------------------------------- * - * copyright (C) 2014-2015 by Thierry Louge * + * copyright (C) 2014-2016 by Thierry Louge * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -34,8 +34,10 @@ #include #include #include "GBase.hpp" -#include "GXml.hpp" -#include "GXmlNode.hpp" + +/* __ Forward declarations _______________________________________________ */ +class GXml; +class GXmlNode; /***********************************************************************//** @@ -73,29 +75,31 @@ protected: void start_hub(void); void handle_request(const socklen_t& sock); void request_ping(const socklen_t& sock); - void request_register(const GXml& xml, + void request_register(const GXml& xml, const socklen_t& sock); - void request_unregister(const GXml& xml, + void request_unregister(const GXml& xml, const socklen_t& sock); - void request_declare_metadata(const GXml& xml, + void request_declare_metadata(const GXml& xml, const socklen_t& sock); - void request_declare_subscriptions(const GXml& xml, + void request_declare_subscriptions(const GXml& xml, const socklen_t& sock); - void request_set_xml_rpc_callback(const GXml& xml, + void request_set_xml_rpc_callback(const GXml& xml, const socklen_t& sock); - void request_get_subscriptions(const GXml& xml, + void request_get_subscriptions(const GXml& xml, const socklen_t& sock); - void request_get_registered_clients(const GXml& xml, + void request_get_registered_clients(const GXml& xml, const socklen_t& sock); - void request_get_subscribed_clients(const GXml& xml, + void request_get_subscribed_clients(const GXml& xml, const socklen_t& sock); - void request_get_metadata(const GXml& xml, + void request_get_metadata(const GXml& xml, const socklen_t& sock); + void request_notify_all(const GXml& xml, + const socklen_t& sock); void request_shutdown(const socklen_t& sock); std::string get_client_key(const GXml& xml) const; int get_client_index(const GXml& xml) const; int get_client_index(const std::string& reference) const; - std::string get_response_value(const GXml& xml, + std::string get_response_value(const GXmlNode* node, const std::string& name) const; void get_name_value_pair(const GXmlNode* node, std::string& name, @@ -103,24 +107,10 @@ protected: std::vector get_subscriptions(const GXml& xml) const; std::string get_callback_url(const GXml& xml) const; std::string get_hub_lockfile(void) const; - void send_notifications(const std::string& method, - const std::string& client); - void send_notifications(const std::string& method, - const std::string& client, - const GXml& xml); - void broadcast(const GXml& xml, const socklen_t& sock); std::string get_mtype(const GXml& xml) const; std::string get_destination(const GXml& xml) const; - // Low-level methods - void create_samp_file(void) const; - void post_samp_ok(const socklen_t& sock) const; - void post_samp_void(const socklen_t& sock) const; - void post_string(const std::string& content, const socklen_t& sock) const; - void notify(const std::string& url, const std::string& notification) const; - std::string random_string(const size_t& length) const; - - // Protected structure + // Client structure struct client { std::string name; std::string private_key; @@ -136,6 +126,24 @@ protected: std::vector subscriptions; }; + // Low-level methods + void create_samp_file(void) const; + void post_samp_ok(const socklen_t& sock) const; + void post_samp_void(const socklen_t& sock) const; + void post_string(const std::string& content, + const socklen_t& sock) const; + void notify(const std::string& url, + const std::string& notification) const; + void notify_register(const client& client, + const std::string& reference); + void notify_unregister(const client& client, + const std::string& reference); + void notify_metadata(const client& client, + const std::string& reference); + void notify_image_load(const client& client, + const GXml& xml); + std::string random_string(const size_t& length) const; + // Protected members std::string m_secret; //!< Secret Hub key std::string m_hub_url; //!< The XML-RPC endpoint for communication with the hub diff --git a/src/vo/GVOClient.cpp b/src/vo/GVOClient.cpp index 6b5693b..4b21f50 100644 --- a/src/vo/GVOClient.cpp +++ b/src/vo/GVOClient.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GVOClient.cpp - VO client class * * ----------------------------------------------------------------------- * - * copyright (C) 2013-2015 by Juergen Knoedlseder * + * copyright (C) 2013-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -35,10 +35,13 @@ #include // getaddrinfo() function #include // socket(), connect() functions #include +#include "GTools.hpp" +#include "GException.hpp" +#include "GXml.hpp" +#include "GXmlNode.hpp" +#include "GFits.hpp" #include "GVOClient.hpp" #include "GVOHub.hpp" -#include "GException.hpp" -#include "GTools.hpp" /* __ Method name definitions ____________________________________________ */ #define G_FIND_HUB "GVOClient::find_hub()" @@ -368,33 +371,54 @@ GXml GVOClient::execute(const std::string& request) const ***************************************************************************/ void GVOClient::publish(const GFitsHDU& hdu) { + // Signal that client should be disconnected after sending the image + // to Hub + bool disconnected = !is_connected(); + + // Make sure that the client is connected to a Hub + if (disconnected) { + connect(); + } + // Save FITS HDU into a temporary file std::string samp_share = std::tmpnam(NULL); GFits fits; fits.append(hdu); fits.saveto(samp_share, true); + // Get FITS extension name + std::string extname = hdu.extname(); + if (extname.empty()) { + extname = "FITS Image"; + } + // Compose notification to be passed to the Hub std::string hub_command = ""; hub_command.append("\n"); - hub_command.append(""); + hub_command.append("\n"); hub_command.append(" samp.hub.notifyAll\n"); hub_command.append(" \n"); hub_command.append(" image.load.fits\n"); hub_command.append(" "+m_secret+"\n"); hub_command.append(" \n"); hub_command.append(" samp.params\n"); - hub_command.append(" nameGammalib_FITS_FILE\n"); + hub_command.append(" name"+extname+"\n"); hub_command.append(" urlfile://localhost"+samp_share+"\n"); hub_command.append(" image-idGammalib Data\n"); hub_command.append(" \n"); hub_command.append(" samp.mtypeimage.load.fits\n"); hub_command.append(" \n"); - hub_command.append(" \n\n"); + hub_command.append(" \n"); + hub_command.append("\n"); // Send notification execute(hub_command); + // Disconnect client from Hub + if (disconnected) { + disconnect(); + } + // Return return; } diff --git a/src/vo/GVOHub.cpp b/src/vo/GVOHub.cpp index ec266ed..f8834db 100644 --- a/src/vo/GVOHub.cpp +++ b/src/vo/GVOHub.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GVOHub.cpp - VO SAMP Hub class * * ----------------------------------------------------------------------- * - * copyright (C) 2014-2015 by Thierry Louge * + * copyright (C) 2014-2016 by Thierry Louge * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -41,9 +41,11 @@ #include // socket(), connect() functions #include // waitpid() function #include // inet_addr() function -#include "GVOHub.hpp" -#include "GException.hpp" #include "GTools.hpp" +#include "GException.hpp" +#include "GXml.hpp" +#include "GXmlNode.hpp" +#include "GVOHub.hpp" /* __ Method name definitions ____________________________________________ */ #define G_START_HUB "GVOHub::start_hub()" @@ -54,6 +56,7 @@ /* __ Debug definitions __________________________________________________ */ #define G_CONSOLE_DUMP +#define G_CONSOLE_ERRORS #define G_SHOW_MESSAGE @@ -429,7 +432,7 @@ void GVOHub::handle_request(const socklen_t& sock) #endif // Extract response into an XML object - GXml xml; + GXml xml; size_t start = message.find(" params > param[1] > value > struct"); + // Store metadata - m_clients[i].name = get_response_value(xml, "samp.name");; - m_clients[i].description = get_response_value(xml, "samp.description.text"); - m_clients[i].icon = get_response_value(xml, "samp.icon.url"); - m_clients[i].documentation = get_response_value(xml, "samp.documentation.url"); - m_clients[i].affiliation = get_response_value(xml, "author.affiliation"); - m_clients[i].email = get_response_value(xml, "author.email"); - m_clients[i].author_name = get_response_value(xml, "author.name"); - m_clients[i].homepage = get_response_value(xml, "home.page"); + m_clients[i].name = get_response_value(node, "samp.name");; + m_clients[i].description = get_response_value(node, "samp.description.text"); + m_clients[i].icon = get_response_value(node, "samp.icon.url"); + m_clients[i].documentation = get_response_value(node, "samp.documentation.url"); + m_clients[i].affiliation = get_response_value(node, "author.affiliation"); + m_clients[i].email = get_response_value(node, "author.email"); + m_clients[i].author_name = get_response_value(node, "author.name"); + m_clients[i].homepage = get_response_value(node, "home.page"); // Post void message post_samp_void(sock); - - // Send notifications - send_notifications("samp.hub.event.metadata", m_clients[i].reference); + + // Notify all clients about the registering + for (int k = 0; k < m_clients.size(); ++k) { + if (i != k) { + for (int j = 0; j < m_clients[k].subscriptions.size(); ++j) { + if ("samp.hub.event.metadata" == m_clients[k].subscriptions[j]) { + notify_metadata(m_clients[k], m_clients[i].reference); + } + } + } + } } // endif: client found // Signal if the client was unknown - #if defined(G_CONSOLE_DUMP) + #if defined(G_CONSOLE_ERRORS) else { - std::cout << " *** ERROR: Unable to find client " << get_client_key(xml) << std::endl; + std::cout << "*** ERROR: GVOHub::request_declare_metadata: "; + std::cout << "Unable to find client \"" << get_client_key(xml); + std::cout << "\"" << std::endl; } #endif @@ -752,9 +781,11 @@ void GVOHub::request_declare_subscriptions(const GXml& xml,const socklen_t& sock } // endif: valid client found // Signal if the client was unknown - #if defined(G_CONSOLE_DUMP) + #if defined(G_CONSOLE_ERRORS) else { - std::cout << " *** ERROR: Unable to find client " << get_client_key(xml) << std::endl; + std::cout << "*** ERROR: GVOHub::request_declare_subscriptions: "; + std::cout << "Unable to find client \"" << get_client_key(xml); + std::cout << "\"" << std::endl; } #endif @@ -797,9 +828,11 @@ void GVOHub::request_set_xml_rpc_callback(const GXml& xml, } // endif: client found // Signal if the client was unknown - #if defined(G_CONSOLE_DUMP) + #if defined(G_CONSOLE_ERRORS) else { - std::cout << " *** ERROR: Unable to find client " << get_client_key(xml) << std::endl; + std::cout << "*** ERROR: GVOHub::request_set_xml_rpc_callback: "; + std::cout << "Unable to find client \"" << get_client_key(xml); + std::cout << "\"" << std::endl; } #endif @@ -871,9 +904,11 @@ void GVOHub::request_get_subscriptions(const GXml& xml, const socklen_t& sock) } // Signal if the client was unknown - #if defined(G_CONSOLE_DUMP) + #if defined(G_CONSOLE_ERRORS) else { - std::cout << " *** ERROR: Unable to find client " << get_client_key(xml) << std::endl; + std::cout << "*** ERROR: GVOHub::request_get_subscriptions: "; + std::cout << "Unable to find client \"" << get_client_key(xml); + std::cout << "\"" << std::endl; } #endif @@ -1092,6 +1127,15 @@ void GVOHub::request_get_metadata(const GXml& xml, const socklen_t& sock) response.append(" \n"); } // endif: index was valid + + // Signal if the client was unknown + #if defined(G_CONSOLE_ERRORS) + else { + std::cout << "*** ERROR: GVOHub::request_get_metadata: "; + std::cout << "Unable to find client \"" << get_client_key(xml); + std::cout << "\"" << std::endl; + } + #endif } // endelse: client was not the hub @@ -1107,52 +1151,56 @@ void GVOHub::request_get_metadata(const GXml& xml, const socklen_t& sock) return; } + /***********************************************************************//** - * @brief Broadcasts a message + * @brief Handle request to notify all clients * * @param[in] xml XML message sent by client. * @param[in] sock Socket. * - * Broadcasts an image to every registered client. + * Handles requests to notify all clients. The method will loop over all + * clients to check the subscriptions of each client, and send a notification + * to all clients that are subscribed to the requested message type. ***************************************************************************/ -void GVOHub::broadcast(const GXml& xml, const socklen_t& sock) +void GVOHub::request_notify_all(const GXml& xml, const socklen_t& sock) { // Header - - // Get client index - int i = get_client_index(xml); - - // Get message mtype - std::string mtype = get_mtype(xml); #if defined(G_CONSOLE_DUMP) - std::cout<<"mtype is: " +mtype + " i value: " + gammalib::str(i)< + * name + * value + * + * + * If the specified parameter @p name was not found, or the the XML @p node + * is NULL, an empty string is returned. ***************************************************************************/ -std::string GVOHub::get_response_value(const GXml& xml, +std::string GVOHub::get_response_value(const GXmlNode* node, const std::string& name) const { - // Declare value + // Declare empty value std::string value = ""; - // Get the client's private key - const GXmlNode* node = xml.element("methodCall > params > param[1] > value > struct"); + // Search for parameter name, and if found, return its value if (node != NULL) { int num = node->elements("member"); for (int i = 0; i < num; ++i) { @@ -1476,322 +1530,6 @@ std::string GVOHub::get_hub_lockfile(void) const /***********************************************************************//** - * @brief Send notifications - * - * @param[in] method Name of the method - * @param[in] client Reference of the client - * - * Send notifications to all registered clients that request so. - ***************************************************************************/ -void GVOHub::send_notifications(const std::string& method, - const std::string& client) -{ - #if defined(G_CONSOLE_DUMP) - std::cout << "GVOHub::send_notifications 1st form" << std::endl; - #endif - // Loop over all clients - for (int i = 0; i < m_clients.size(); ++i) { - - // Loop over all methods - for (int j = 0; j < m_clients[i].subscriptions.size(); ++j) { - - // Continue only if method matches - if (method == m_clients[i].subscriptions[j]) { - - // Declare notification - std::string msg = ""; - - // Register - if (method == "samp.hub.event.register") { - - // Set response for samp.hub.event.register - msg.append("\n"); - msg.append("\n"); - msg.append("samp.client.receiveNotification\n"); - msg.append("\n"); - msg.append(" "); - msg.append(m_clients[i].private_key); - msg.append("\n"); - msg.append(" "+m_hub_id+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.mtype\n"); - msg.append(" samp.hub.event.register\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.params\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" id\n"); - msg.append(" "+client+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append("\n"); - msg.append("\n"); - - // Post notification - notify(m_clients[i].url, msg); - - } - - // Unregister - else if (method == "samp.hub.event.unregister") { - - // Set response for samp.hub.event.unregister - msg.append("\n"); - msg.append("\n"); - msg.append("samp.client.receiveNotification\n"); - msg.append("\n"); - msg.append(" "); - msg.append(m_clients[i].private_key); - msg.append("\n"); - msg.append(" "); - msg.append(m_hub_id); - msg.append("\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.mtype\n"); - msg.append(" samp.hub.event.unregister\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.params\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" id\n"); - msg.append(" "+client+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append("\n"); - msg.append("\n"); - - // Post notification - notify(m_clients[i].url, msg); - - } - - // Metadata - else if (method == "samp.hub.event.metadata") { - - // Get index of client - int k; - for (k = 0; k < m_clients.size(); ++k) { - if (m_clients[k].reference == client) { - break; - } - } - - // Fall through if client index is not valid - if (k >= m_clients.size()) { - continue; - } - - // Set response for samp.hub.event.metadata - msg.append("\n"); - msg.append("samp.client.receiveNotification\n"); - msg.append("\n"); - msg.append(" "); - msg.append(m_clients[i].private_key); - msg.append("\n"); - msg.append(" "+m_hub_id+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.mtype\n"); - msg.append(" samp.hub.event.metadata\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.params\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" id\n"); - msg.append(" "+m_clients[k].reference+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" metadata\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.name\n"); - msg.append(" "+m_clients[k].name+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.description.text\n"); - msg.append(" "+m_clients[k].description+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.icon.url\n"); - msg.append(" "+m_clients[k].icon+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.documentation.url\n"); - msg.append(" "+m_clients[k].documentation+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" author.affiliation\n"); - msg.append(" "+m_clients[k].affiliation+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" author.name\n"); - msg.append(" "+m_clients[k].author_name+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" author.email\n"); - msg.append(" "+m_clients[k].email+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" home.page\n"); - msg.append(" "+m_clients[k].homepage+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append("\n"); - msg.append("\n"); - - // Post notification - notify(m_clients[i].url, msg); - - } // endelse: metadata - - } // endif: method was requested one - - } // endfor: looped over all methods - - } // endfor: looped over all clients - - // Return - return; -} -/***********************************************************************//** - * @brief Send notifications - * - * @param[in] method Name of the method - * @param[in] client Reference of the client - * @param[in] xml message sent by the client - * - * Send notifications to all registered clients that request so. - ***************************************************************************/ -void GVOHub::send_notifications(const std::string& method, - const std::string& client, - const GXml& xml) -{ - // Debug: dump information to console - #if defined(G_CONSOLE_DUMP) - std::cout << "GVOHub::send_notifications 2nd form" << std::endl; - std::cout << "GVOHub::send_notifications "+method << std::endl; - #endif - - // Loop over all clients - for (int i = 0; i < m_clients.size(); ++i) { - - // Loop over all methods - for (int j = 0; j < m_clients[i].subscriptions.size(); ++j) { - - // Continue only if method matches - if (method == m_clients[i].subscriptions[j]) { - - // Declare notification - std::string msg = ""; - - // Image loading - if (method == "image.load.fits") { - - // Debug: dump information to console - #if defined(G_CONSOLE_DUMP) - std::cout << "GVOHub:: Preparing broadcast message" << std::endl; - #endif - - // Declare value - std::string value = ""; - - // Search for value of specified member - const GXmlNode* node = xml.element("methodCall > params > param[2] > value > struct > member > value > struct"); - #if defined(G_CONSOLE_DUMP) - std::cout << "Searching url value" << std::endl; - #endif - if (node != NULL) { - #if defined(G_CONSOLE_DUMP) - std::cout << "Node found" << std::endl; - #endif - int num = node->elements("member"); - for (int i = 0; i < num; ++i) { - const GXmlNode* member = node->element("member", i); - std::string one_name; - std::string one_value; - get_name_value_pair(member, one_name, one_value); - #if defined(G_CONSOLE_DUMP) - std::cout << "name: "+one_name << std::endl; - #endif - if (one_name == "url") { - value = one_value; - break; - } - } - } else { - #if defined(G_CONSOLE_DUMP) - std::cout << "Node not found" << std::endl; - #endif - } - - // Set response for image.load.fits - msg.append("\n"); - msg.append("\n"); - msg.append("samp.client.receiveNotification\n"); - msg.append("\n"); - msg.append(" "); - msg.append(m_clients[i].private_key); - msg.append("\n"); - msg.append(" "); - msg.append(m_hub_id); - msg.append("\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.mtype\n"); - msg.append(" image.load.fits\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" samp.params\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" name\n"); - msg.append(" Gammalib_shared_fits\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" image-id\n"); - msg.append(" Gammalib_shared_fits_id\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" url\n"); - msg.append(" "+value+"\n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append(" \n"); - msg.append("\n"); - msg.append("\n"); - #if defined(G_CONSOLE_DUMP) - std::cout << msg << std::endl; - #endif - - // Post notification - notify(m_clients[i].url, msg); - - } - } // endif: method was requested one - - } // endfor: looped over all methods - - } // endfor: looped over all clients - - // Return - return; -} - -/***********************************************************************//** * @brief Creates the lockfile, fill it * * Implements IVOA standard REC-SAMP-1.3-20120411. @@ -2076,6 +1814,264 @@ void GVOHub::notify(const std::string& url, /***********************************************************************//** + * @brief Notify client about another client registering at Hub + * + * @param[in] client Client to notify. + * @param[in] reference Reference to client which registered. + * + * Notify a client about another client that has registered at the Hub. The + * method sends a "samp.hub.event.register" message to the @p client. + ***************************************************************************/ +void GVOHub::notify_register(const GVOHub::client& client, + const std::string& reference) +{ + // Declare notification + std::string msg = ""; + + // Set response for samp.hub.event.register + msg.append("\n"); + msg.append("\n"); + msg.append("samp.client.receiveNotification\n"); + msg.append("\n"); + msg.append(" "+client.private_key+"\n"); + msg.append(" "+m_hub_id+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.mtype\n"); + msg.append(" samp.hub.event.register\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.params\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" id\n"); + msg.append(" "+reference+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append("\n"); + msg.append("\n"); + + // Post notification + notify(client.url, msg); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Notify client about another client unregistering at Hub + * + * @param[in] client Client to notify. + * @param[in] reference Reference to client who unregistered. + * + * Notify a client about another client that has unregistered at the Hub. The + * method sends a "samp.hub.event.unregister" message to the @p client. + ***************************************************************************/ +void GVOHub::notify_unregister(const GVOHub::client& client, + const std::string& reference) +{ + // Declare notification + std::string msg = ""; + + // Set response for samp.hub.event.unregister + msg.append("\n"); + msg.append("\n"); + msg.append("samp.client.receiveNotification\n"); + msg.append("\n"); + msg.append(" "+client.private_key+"\n"); + msg.append(" "+m_hub_id+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.mtype\n"); + msg.append(" samp.hub.event.unregister\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.params\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" id\n"); + msg.append(" "+reference+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append("\n"); + msg.append("\n"); + + // Post notification + notify(client.url, msg); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Notify client about the metadata of another client + * + * @param[in] client Client to notify. + * @param[in] reference Reference of client for which metadata should be sent. + * + * Notify a client about another the metadata of another client. The method + * sends a "samp.hub.event.metadata" message to the @p client. + ***************************************************************************/ +void GVOHub::notify_metadata(const GVOHub::client& client, + const std::string& reference) +{ + // Get index of reference client + int k; + for (k = 0; k < m_clients.size(); ++k) { + if (m_clients[k].reference == reference) { + break; + } + } + + // Continue only if client index is valid + if (k < m_clients.size()) { + + // Declare notification + std::string msg = ""; + + // Set response for samp.hub.event.metadata + msg.append("\n"); + msg.append("samp.client.receiveNotification\n"); + msg.append("\n"); + msg.append(" "+client.private_key+"\n"); + msg.append(" "+m_hub_id+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.mtype\n"); + msg.append(" samp.hub.event.metadata\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.params\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" id\n"); + msg.append(" "+m_clients[k].reference+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" metadata\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.name\n"); + msg.append(" "+m_clients[k].name+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.description.text\n"); + msg.append(" "+m_clients[k].description+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.icon.url\n"); + msg.append(" "+m_clients[k].icon+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.documentation.url\n"); + msg.append(" "+m_clients[k].documentation+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" author.affiliation\n"); + msg.append(" "+m_clients[k].affiliation+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" author.name\n"); + msg.append(" "+m_clients[k].author_name+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" author.email\n"); + msg.append(" "+m_clients[k].email+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" home.page\n"); + msg.append(" "+m_clients[k].homepage+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append("\n"); + msg.append("\n"); + + // Post notification + notify(client.url, msg); + + } // endif: reference client was valid + + // Return + return; +} + + +/***********************************************************************//** + * @brief Notify client about image loading + * + * @param[in] client Client. + * @param[in] xml Message from which image information is extracted. + * + * Notify a client that a FITS image is avialable for loading. The method + * sends a "image.load.fits" message to the @p client. Information about the + * image is extracted from the @p xml document. + ***************************************************************************/ +void GVOHub::notify_image_load(const GVOHub::client& client, + const GXml& xml) +{ + // Get client response + const GXmlNode* node = xml.element("methodCall > params > param[2] > value > struct > member > value > struct"); + + // Extract image information from client response + std::string name = get_response_value(node, "name"); + std::string url = get_response_value(node, "url"); + std::string id = get_response_value(node, "image-id"); + + // Declare notification + std::string msg = ""; + + // Set notification for image.load.fits + msg.append("\n"); + msg.append("\n"); + msg.append("samp.client.receiveNotification\n"); + msg.append("\n"); + msg.append(" "+client.private_key+"\n"); + msg.append(" "+m_hub_id+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.mtype\n"); + msg.append(" image.load.fits\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" samp.params\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" name\n"); + msg.append(" "+name+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" image-id\n"); + msg.append(" "+id+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" url\n"); + msg.append(" "+url+"\n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append(" \n"); + msg.append("\n"); + msg.append("\n"); + + // Post notification + notify(client.url, msg); + + // Return + return; +} + + +/***********************************************************************//** * @brief Generates random string of characters * * @param[in] length Length of random string @@ -2093,6 +2089,8 @@ std::string GVOHub::random_string(const size_t& length) const // Return string return str; } + + /***********************************************************************//** * @brief Extract mtype from XML request * @@ -2122,6 +2120,8 @@ std::string GVOHub::get_mtype(const GXml& xml) const // Return key return client_key; } + + /***********************************************************************//** * @brief Extract client destination from XML request * @@ -2133,7 +2133,7 @@ std::string GVOHub::get_destination(const GXml& xml) const { // Header #if defined(G_CONSOLE_DUMP) - std::cout << "GVOHub::get_mtype" << std::endl; + std::cout << "GVOHub::get_destination" << std::endl; #endif // Initialise response -- libgit2 0.21.4