From 193fe22ef0f32091063c1a960968f3983a5874bc Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Thu, 26 Feb 2015 17:47:01 +0100 Subject: [PATCH] Addition of module_feedback_send Addition of module_feedback_send. Every 30 second data is sent to 127.0.0.1 Missing routines for configuration parameters and blocking the send after successful completion --- server/core/load_utils.c | 160 +++++++++++++++++++++++++++++++++++++-- server/core/service.c | 5 ++ server/include/config.h | 12 +++ server/include/modules.h | 15 ++-- 4 files changed, 180 insertions(+), 12 deletions(-) diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 3fe975f5c..1fd6b1ab9 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -23,12 +23,13 @@ * @verbatim * Revision History * - * Date Who Description - * 13/06/13 Mark Riddoch Initial implementation - * 14/06/13 Mark Riddoch Updated to add call to ModuleInit if one is - * defined in the loaded module. - * Also updated to call fixed GetModuleObject - * 02/06/14 Mark Riddoch Addition of module info + * Date Who Description + * 13/06/13 Mark Riddoch Initial implementation + * 14/06/13 Mark Riddoch Updated to add call to ModuleInit if one is + * defined in the loaded module. + * Also updated to call fixed GetModuleObject + * 02/06/14 Mark Riddoch Addition of module info + * 26/02/15 Massimiliano Pinto Addition of module_feedback_send * * @endverbatim */ @@ -42,6 +43,8 @@ #include #include #include +#include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; @@ -59,6 +62,31 @@ static void register_module(const char *module, MODULE_INFO *info); static void unregister_module(const char *module); +struct MemoryStruct { + char *data; + size_t size; +}; + +static size_t +WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)userp; + + mem->data = realloc(mem->data, mem->size + realsize + 1); + if(mem->data == NULL) { + /* out of memory! */ + printf("not enough memory (realloc returned NULL)\n"); + return 0; + } + + memcpy(&(mem->data[mem->size]), contents, realsize); + mem->size += realsize; + mem->data[mem->size] = 0; + + return realsize; +} + char* get_maxscale_home(void) { char* home = getenv("MAXSCALE_HOME"); @@ -408,3 +436,123 @@ MODULES *ptr = registered; } dcb_printf(dcb, "----------------+-------------+---------+-------+-------------------------\n\n"); } + +/** + * Send loaded modules info to notification service + * + * @param data The configuration details of notification service + */ +void +module_feedback_send(void* data) +{ + MODULES *ptr = registered; + CURL *curl; + CURLcode res; + struct curl_httppost *formpost=NULL; + struct curl_httppost *lastptr=NULL; + GWBUF *buffer = NULL; + char *data_ptr = NULL; + int n_mod=0; + struct MemoryStruct chunk; + + chunk.data = malloc(1); /* will be grown as needed by the realloc above */ + chunk.size = 0; /* no data at this point */ + + /* count loaded modules */ + while (ptr) + { + ptr = ptr->next; + n_mod++; + } + ptr = registered; + + buffer = gwbuf_alloc(n_mod * 256); + data_ptr = GWBUF_DATA(buffer); + + while (ptr) + { + /* current maxscale setup */ + sprintf(data_ptr, "FEEDBACK_SERVER_UID\t%s\n", "xxxfcBRIvkRlxyGdoJL0bWy+TmY"); + data_ptr+=strlen(data_ptr); + sprintf(data_ptr, "FEEDBACK_USER_INFO\t%s\n", "0467009f-xxxx-yyyy-zzzz-b6b2ec9c6cf4"); + data_ptr+=strlen(data_ptr); + sprintf(data_ptr, "VERSION\t%s\n", MAXSCALE_VERSION); + data_ptr+=strlen(data_ptr); + sprintf(data_ptr, "NOW\t%lu\nPRODUCT\t%s\n", time(NULL), "maxscale"); + data_ptr+=strlen(data_ptr); + sprintf(data_ptr, "Uname_sysname\t%s\n", "linux"); + data_ptr+=strlen(data_ptr); + sprintf(data_ptr, "Uname_distribution\t%s\n", "centos"); + data_ptr+=strlen(data_ptr); + + /* modules data */ + sprintf(data_ptr, "module_%s_type\t%s\nmodule_%s_version\t%s\n", ptr->module, ptr->type, ptr->module, ptr->version); + data_ptr+=strlen(data_ptr); + + if (ptr->info) { + sprintf(data_ptr, "module_%s_api\t%d.%d.%d\n", + ptr->module, + ptr->info->api_version.major, + ptr->info->api_version.minor, + ptr->info->api_version.patch); + + data_ptr+=strlen(data_ptr); + sprintf(data_ptr, "module_%s_releasestatus\t%s\n", + ptr->module, + ptr->info->status == MODULE_IN_DEVELOPMENT + ? "In Development" + : (ptr->info->status == MODULE_ALPHA_RELEASE + ? "Alpha" + : (ptr->info->status == MODULE_BETA_RELEASE + ? "Beta" + : (ptr->info->status == MODULE_GA + ? "GA" + : (ptr->info->status == MODULE_EXPERIMENTAL + ? "Experimental" : "Unknown"))))); + data_ptr+=strlen(data_ptr); + } + ptr = ptr->next; + } + + /* curl API call for data send via HTTP POST using a "file" type input */ + curl = curl_easy_init(); + + if(curl) { + curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "data", + CURLFORM_BUFFER, "report.txt", + CURLFORM_BUFFERPTR, (char *)GWBUF_DATA(buffer), + CURLFORM_BUFFERLENGTH, strlen((char *)GWBUF_DATA(buffer)), + CURLFORM_CONTENTTYPE, "text/plain", + CURLFORM_END); + + curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1/post.php"); + curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); + + /* send all received data to this function */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + + /* we pass our 'chunk' struct to the callback function */ + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); + + /* some servers don't like requests that are made without a user-agent field, so we provide one */ + curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + else + fprintf(stderr, "Reply from remote server is\n[%s]\n", chunk.data); + } + + if(chunk.data) + free(chunk.data); + + gwbuf_free(buffer); + curl_easy_cleanup(curl); + curl_formfree(formpost); +} diff --git a/server/core/service.c b/server/core/service.c index a9b34d2bc..e766263b0 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -474,6 +474,11 @@ serviceStartAll() SERVICE *ptr; int n = 0,i; + /** Add the notification service feedback task, if enabled */ + //if (config_feedback_enable() ) { + hktask_add("send_feedback", module_feedback_send, NULL, 30); + //} + ptr = allServices; while (ptr && !ptr->svc_do_shutdown) { diff --git a/server/include/config.h b/server/include/config.h index 93bd095c1..c27184468 100644 --- a/server/include/config.h +++ b/server/include/config.h @@ -30,6 +30,7 @@ * 07/05/14 Massimiliano Pinto Added version_string to global configuration * 23/05/14 Massimiliano Pinto Added id to global configuration * 17/10/14 Mark Riddoch Added poll tuning configuration parameters + * 26/02/15 Massimiliano Pinto Added notification service configuration parameters * * @endverbatim */ @@ -99,6 +100,17 @@ typedef struct { unsigned int pollsleep; /**< Wait time in blocking polls */ } GATEWAY_CONF; +/** + * The configuration and usage information data for feeback service + */ +typedef struct { + int feedback_enable; /**< Enable/Disable Notification feedback */ + char *feedback_url; /**< URL to which the data is sent */ + char *feedback_user_info; /**< User info included in the feedback data sent */ + char *feedback_server_uid; /**< Installation identifier included in the feedback data sent */ + int feedback_send_timeout; /**< An attempt to send the data times out and fails after this many seconds */ +} FEEDBACK_CONF; + extern int config_load(char *); extern int config_reload(); extern int config_threadcount(); diff --git a/server/include/modules.h b/server/include/modules.h index adda2b255..674241075 100644 --- a/server/include/modules.h +++ b/server/include/modules.h @@ -28,12 +28,14 @@ * @verbatim * Revision History * - * Date Who Description - * 13/06/13 Mark Riddoch Initial implementation - * 08/07/13 Mark Riddoch Addition of monitor modules - * 29/05/14 Mark Riddoch Addition of filter modules - * 01/10/14 Mark Riddoch Addition of call to unload all modules on - * shutdown + * Date Who Description + * 13/06/13 Mark Riddoch Initial implementation + * 08/07/13 Mark Riddoch Addition of monitor modules + * 29/05/14 Mark Riddoch Addition of filter modules + * 01/10/14 Mark Riddoch Addition of call to unload all modules on + * shutdown + * 26/02/15 Massimiliano Pinto Addition of module_feedback_send + * * @endverbatim */ @@ -64,5 +66,6 @@ extern void unload_all_modules(); extern void printModules(); extern void dprintAllModules(DCB *); char* get_maxscale_home(void); +extern void module_feedback_send(void*); #endif